| Directory: | ./ |
|---|---|
| File: | sql/sql_parse.cc |
| Date: | 2022-12-13 11:44:05 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 3557 | 3769 | 94.4% |
| Branches: | 3925 | 6489 | 60.5% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* Copyright (c) 1999, 2022, Oracle and/or its affiliates. | ||
| 2 | |||
| 3 | This program is free software; you can redistribute it and/or modify | ||
| 4 | it under the terms of the GNU General Public License, version 2.0, | ||
| 5 | as published by the Free Software Foundation. | ||
| 6 | |||
| 7 | This program is also distributed with certain software (including | ||
| 8 | but not limited to OpenSSL) that is licensed under separate terms, | ||
| 9 | as designated in a particular file or component or in included license | ||
| 10 | documentation. The authors of MySQL hereby grant you an additional | ||
| 11 | permission to link the program and your derivative works with the | ||
| 12 | separately licensed software that they have included with MySQL. | ||
| 13 | |||
| 14 | This program is distributed in the hope that it will be useful, | ||
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | GNU General Public License, version 2.0, for more details. | ||
| 18 | |||
| 19 | You should have received a copy of the GNU General Public License | ||
| 20 | along with this program; if not, write to the Free Software | ||
| 21 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ | ||
| 22 | |||
| 23 | #include "sql/sql_parse.h" | ||
| 24 | |||
| 25 | #include <algorithm> | ||
| 26 | #include <atomic> | ||
| 27 | #include <climits> | ||
| 28 | #include <cstdint> | ||
| 29 | #include <cstdio> | ||
| 30 | #include <cstdlib> | ||
| 31 | #include <cstring> | ||
| 32 | #include <functional> | ||
| 33 | #include <iterator> | ||
| 34 | #include <memory> | ||
| 35 | #include <optional> | ||
| 36 | #include <string> | ||
| 37 | #include <utility> | ||
| 38 | #include <vector> | ||
| 39 | |||
| 40 | #include "my_config.h" | ||
| 41 | #ifdef HAVE_LSAN_DO_RECOVERABLE_LEAK_CHECK | ||
| 42 | #include <sanitizer/lsan_interface.h> | ||
| 43 | #endif | ||
| 44 | |||
| 45 | #include "dur_prop.h" | ||
| 46 | #include "field_types.h" // enum_field_types | ||
| 47 | #include "m_ctype.h" | ||
| 48 | #include "m_string.h" | ||
| 49 | #include "mem_root_deque.h" | ||
| 50 | #include "mutex_lock.h" // MUTEX_LOCK | ||
| 51 | #include "my_alloc.h" | ||
| 52 | #include "my_compiler.h" | ||
| 53 | #include "my_dbug.h" | ||
| 54 | #include "my_hostname.h" | ||
| 55 | #include "my_inttypes.h" // TODO: replace with cstdint | ||
| 56 | #include "my_io.h" | ||
| 57 | #include "my_loglevel.h" | ||
| 58 | #include "my_macros.h" | ||
| 59 | #include "my_psi_config.h" | ||
| 60 | #include "my_sys.h" | ||
| 61 | #include "my_table_map.h" | ||
| 62 | #include "my_thread_local.h" | ||
| 63 | #include "my_time.h" | ||
| 64 | #include "mysql/com_data.h" | ||
| 65 | #include "mysql/components/services/bits/plugin_audit_connection_types.h" // MYSQL_AUDIT_CONNECTION_CHANGE_USER | ||
| 66 | #include "mysql/components/services/bits/psi_statement_bits.h" // PSI_statement_info | ||
| 67 | #include "mysql/components/services/log_builtins.h" // LogErr | ||
| 68 | #include "mysql/plugin_audit.h" | ||
| 69 | #include "mysql/psi/mysql_mutex.h" | ||
| 70 | #include "mysql/psi/mysql_rwlock.h" | ||
| 71 | #include "mysql/psi/mysql_statement.h" | ||
| 72 | #include "mysql/service_mysql_alloc.h" | ||
| 73 | #include "mysql/udf_registration_types.h" | ||
| 74 | #include "mysql_version.h" | ||
| 75 | #include "mysqld_error.h" | ||
| 76 | #include "mysys_err.h" // EE_CAPACITY_EXCEEDED | ||
| 77 | #include "pfs_thread_provider.h" | ||
| 78 | #include "prealloced_array.h" | ||
| 79 | #include "scope_guard.h" | ||
| 80 | #include "sql/auth/auth_acls.h" | ||
| 81 | #include "sql/auth/sql_security_ctx.h" | ||
| 82 | #include "sql/binlog.h" // purge_source_logs | ||
| 83 | #include "sql/clone_handler.h" | ||
| 84 | #include "sql/comp_creator.h" | ||
| 85 | #include "sql/create_field.h" | ||
| 86 | #include "sql/current_thd.h" | ||
| 87 | #include "sql/dd/cache/dictionary_client.h" // dd::cache::Dictionary_client::Auto_releaser | ||
| 88 | #include "sql/dd/dd.h" // dd::get_dictionary | ||
| 89 | #include "sql/dd/dd_schema.h" // Schema_MDL_locker | ||
| 90 | #include "sql/dd/dictionary.h" // dd::Dictionary::is_system_view_name | ||
| 91 | #include "sql/dd/info_schema/table_stats.h" | ||
| 92 | #include "sql/dd/types/column.h" | ||
| 93 | #include "sql/debug_sync.h" // DEBUG_SYNC | ||
| 94 | #include "sql/derror.h" // ER_THD | ||
| 95 | #include "sql/discrete_interval.h" | ||
| 96 | #include "sql/error_handler.h" // Strict_error_handler | ||
| 97 | #include "sql/events.h" // Events | ||
| 98 | #include "sql/field.h" | ||
| 99 | #include "sql/gis/srid.h" | ||
| 100 | #include "sql/item.h" | ||
| 101 | #include "sql/item_cmpfunc.h" | ||
| 102 | #include "sql/item_func.h" | ||
| 103 | #include "sql/item_subselect.h" | ||
| 104 | #include "sql/item_timefunc.h" // Item_func_unix_timestamp | ||
| 105 | #include "sql/key_spec.h" // Key_spec | ||
| 106 | #include "sql/locked_tables_list.h" | ||
| 107 | #include "sql/log.h" // query_logger | ||
| 108 | #include "sql/log_event.h" // slave_execute_deferred_events | ||
| 109 | #include "sql/mdl.h" | ||
| 110 | #include "sql/mem_root_array.h" | ||
| 111 | #include "sql/mysqld.h" // stage_execution_of_init_command | ||
| 112 | #include "sql/mysqld_thd_manager.h" // Find_thd_with_id | ||
| 113 | #include "sql/nested_join.h" | ||
| 114 | #include "sql/opt_hints.h" | ||
| 115 | #include "sql/opt_trace.h" // Opt_trace_start | ||
| 116 | #include "sql/parse_location.h" | ||
| 117 | #include "sql/parse_tree_node_base.h" | ||
| 118 | #include "sql/parse_tree_nodes.h" | ||
| 119 | #include "sql/parser_yystype.h" | ||
| 120 | #include "sql/persisted_variable.h" | ||
| 121 | #include "sql/protocol.h" | ||
| 122 | #include "sql/protocol_classic.h" | ||
| 123 | #include "sql/psi_memory_key.h" | ||
| 124 | #include "sql/query_options.h" | ||
| 125 | #include "sql/query_result.h" | ||
| 126 | #include "sql/resourcegroups/resource_group_basic_types.h" | ||
| 127 | #include "sql/resourcegroups/resource_group_mgr.h" // Resource_group_mgr::instance | ||
| 128 | #include "sql/rpl_context.h" | ||
| 129 | #include "sql/rpl_filter.h" // rpl_filter | ||
| 130 | #include "sql/rpl_group_replication.h" // group_replication_start | ||
| 131 | #include "sql/rpl_gtid.h" | ||
| 132 | #include "sql/rpl_handler.h" // launch_hook_trans_begin | ||
| 133 | #include "sql/rpl_replica.h" // change_master_cmd | ||
| 134 | #include "sql/rpl_source.h" // register_slave | ||
| 135 | #include "sql/rpl_utility.h" | ||
| 136 | #include "sql/session_tracker.h" | ||
| 137 | #include "sql/set_var.h" | ||
| 138 | #include "sql/sp.h" // sp_create_routine | ||
| 139 | #include "sql/sp_cache.h" // sp_cache_enforce_limit | ||
| 140 | #include "sql/sp_head.h" // sp_head | ||
| 141 | #include "sql/sp_instr.h" | ||
| 142 | #include "sql/sp_rcontext.h" | ||
| 143 | #include "sql/sql_admin.h" | ||
| 144 | #include "sql/sql_alter.h" | ||
| 145 | #include "sql/sql_audit.h" // MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER | ||
| 146 | #include "sql/sql_backup_lock.h" | ||
| 147 | #include "sql/sql_base.h" // find_temporary_table | ||
| 148 | #include "sql/sql_binlog.h" // mysql_client_binlog_statement | ||
| 149 | #include "sql/sql_check_constraint.h" | ||
| 150 | #include "sql/sql_class.h" | ||
| 151 | #include "sql/sql_cmd.h" | ||
| 152 | #include "sql/sql_connect.h" // decrease_user_connections | ||
| 153 | #include "sql/sql_const.h" | ||
| 154 | #include "sql/sql_db.h" // mysql_change_db | ||
| 155 | #include "sql/sql_digest.h" | ||
| 156 | #include "sql/sql_digest_stream.h" | ||
| 157 | #include "sql/sql_error.h" | ||
| 158 | #include "sql/sql_handler.h" // mysql_ha_rm_tables | ||
| 159 | #include "sql/sql_help.h" // mysqld_help | ||
| 160 | #include "sql/sql_lex.h" | ||
| 161 | #include "sql/sql_list.h" | ||
| 162 | #include "sql/sql_prepare.h" // mysql_stmt_execute | ||
| 163 | #include "sql/sql_profile.h" | ||
| 164 | #include "sql/sql_query_rewrite.h" // invoke_pre_parse_rewrite_plugins | ||
| 165 | #include "sql/sql_reload.h" // handle_reload_request | ||
| 166 | #include "sql/sql_rename.h" // mysql_rename_tables | ||
| 167 | #include "sql/sql_rewrite.h" // mysql_rewrite_query | ||
| 168 | #include "sql/sql_show.h" // find_schema_table | ||
| 169 | #include "sql/sql_table.h" // mysql_create_table | ||
| 170 | #include "sql/sql_trigger.h" // add_table_for_trigger | ||
| 171 | #include "sql/sql_udf.h" | ||
| 172 | #include "sql/sql_view.h" // mysql_create_view | ||
| 173 | #include "sql/sql_zip_dict.h" // mysqld_create_zip_dict, mysqld_drop_zip_dict | ||
| 174 | #include "sql/strfunc.h" | ||
| 175 | #include "sql/system_variables.h" // System_status_var | ||
| 176 | #include "sql/table.h" | ||
| 177 | #include "sql/table_cache.h" // table_cache_manager | ||
| 178 | #include "sql/thd_raii.h" | ||
| 179 | #include "sql/transaction.h" // trans_rollback_implicit | ||
| 180 | #include "sql/transaction_info.h" | ||
| 181 | #include "sql/userstat.h" | ||
| 182 | #include "sql_string.h" | ||
| 183 | #include "template_utils.h" | ||
| 184 | #include "thr_lock.h" | ||
| 185 | #include "violite.h" | ||
| 186 | |||
| 187 | #ifdef WITH_LOCK_ORDER | ||
| 188 | #include "sql/debug_lock_order.h" | ||
| 189 | #endif /* WITH_LOCK_ORDER */ | ||
| 190 | |||
| 191 | #ifdef WITH_WSREP | ||
| 192 | #include "wsrep_binlog.h" | ||
| 193 | #include "wsrep_mysqld.h" | ||
| 194 | #include "wsrep_sst.h" | ||
| 195 | #include "wsrep_thd.h" | ||
| 196 | #include "wsrep_trans_observer.h" | ||
| 197 | |||
| 198 | static bool wsrep_dispatch_sql_command(THD *thd, const char *rawbuf, | ||
| 199 | uint length, Parser_state *parser_state, | ||
| 200 | bool update_userstat); | ||
| 201 | #endif /* WITH_WSREP */ | ||
| 202 | |||
| 203 | namespace resourcegroups { | ||
| 204 | class Resource_group; | ||
| 205 | } // namespace resourcegroups | ||
| 206 | struct mysql_rwlock_t; | ||
| 207 | |||
| 208 | namespace dd { | ||
| 209 | class Schema; | ||
| 210 | } // namespace dd | ||
| 211 | |||
| 212 | namespace dd { | ||
| 213 | class Abstract_table; | ||
| 214 | } // namespace dd | ||
| 215 | |||
| 216 | using std::max; | ||
| 217 | |||
| 218 | /** | ||
| 219 | @defgroup Runtime_Environment Runtime Environment | ||
| 220 | @{ | ||
| 221 | */ | ||
| 222 | |||
| 223 | /* Used in error handling only */ | ||
| 224 | #define SP_COM_STRING(LP) \ | ||
| 225 | ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \ | ||
| 226 | (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \ | ||
| 227 | (LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \ | ||
| 228 | (LP)->sql_command == SQLCOM_DROP_FUNCTION \ | ||
| 229 | ? "FUNCTION" \ | ||
| 230 | : "PROCEDURE") | ||
| 231 | |||
| 232 | static void sql_kill(THD *thd, my_thread_id id, bool only_kill_query); | ||
| 233 | |||
| 234 | const std::array<const std::string, COM_END + 1> Command_names::m_names = { | ||
| 235 | "Sleep", | ||
| 236 | "Quit", | ||
| 237 | "Init DB", | ||
| 238 | "Query", | ||
| 239 | "Field List", | ||
| 240 | "Create DB", | ||
| 241 | "Drop DB", | ||
| 242 | "Refresh", | ||
| 243 | "Shutdown", | ||
| 244 | "Statistics", | ||
| 245 | "Processlist", | ||
| 246 | "Connect", | ||
| 247 | "Kill", | ||
| 248 | "Debug", | ||
| 249 | "Ping", | ||
| 250 | "Time", | ||
| 251 | "Delayed insert", | ||
| 252 | "Change user", | ||
| 253 | "Binlog Dump", | ||
| 254 | "Table Dump", | ||
| 255 | "Connect Out", | ||
| 256 | "Register Replica", | ||
| 257 | "Prepare", | ||
| 258 | "Execute", | ||
| 259 | "Long Data", | ||
| 260 | "Close stmt", | ||
| 261 | "Reset stmt", | ||
| 262 | "Set option", | ||
| 263 | "Fetch", | ||
| 264 | "Daemon", | ||
| 265 | "Binlog Dump GTID", | ||
| 266 | "Reset Connection", | ||
| 267 | "clone", | ||
| 268 | "Group Replication Data Stream subscription", | ||
| 269 | "Error" // Last command number | ||
| 270 | }; | ||
| 271 | |||
| 272 | 14273 | const std::string &Command_names::translate(const System_variables &sysvars) { | |
| 273 | 14273 | terminology_use_previous::enum_compatibility_version version = | |
| 274 | static_cast<terminology_use_previous::enum_compatibility_version>( | ||
| 275 | 14273 | sysvars.terminology_use_previous); | |
| 276 |
3/4✓ Branch 0 taken 13 times.
✓ Branch 1 taken 14260 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
14273 | if (version != terminology_use_previous::NONE && version <= m_replace_version) |
| 277 | 13 | return m_replace_str; | |
| 278 | 14260 | return m_names[m_replace_com]; | |
| 279 | } | ||
| 280 | |||
| 281 | 101812 | const std::string &Command_names::str_session(enum_server_command cmd) { | |
| 282 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 101812 times.
|
101812 | assert(current_thd); |
| 283 |
5/6✓ Branch 0 taken 20 times.
✓ Branch 1 taken 101792 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 101792 times.
✓ Branch 5 taken 20 times.
|
101812 | if (cmd != m_replace_com || current_thd == nullptr) return m_names[cmd]; |
| 284 | 20 | return translate(current_thd->variables); | |
| 285 | } | ||
| 286 | |||
| 287 | 39342272 | const std::string &Command_names::str_global(enum_server_command cmd) { | |
| 288 |
2/2✓ Branch 0 taken 39328333 times.
✓ Branch 1 taken 13939 times.
|
39342272 | if (cmd != m_replace_com) return m_names[cmd]; |
| 289 | 13939 | return translate(global_system_variables); | |
| 290 | } | ||
| 291 | |||
| 292 | const std::string Command_names::m_replace_str{"Register Slave"}; | ||
| 293 | |||
| 294 | 21364066 | bool command_satisfy_acl_cache_requirement(unsigned command) { | |
| 295 |
2/2✓ Branch 0 taken 37676 times.
✓ Branch 1 taken 21326390 times.
|
21401742 | return !((sql_command_flags[command] & CF_REQUIRE_ACL_CACHE) > 0 && |
| 296 |
1/2✓ Branch 0 taken 38093 times.
✗ Branch 1 not taken.
|
21401742 | skip_grant_tables()); |
| 297 | } | ||
| 298 | |||
| 299 | /** | ||
| 300 | Returns true if all tables should be ignored. | ||
| 301 | */ | ||
| 302 | 533598 | bool all_tables_not_ok(THD *thd, TABLE_LIST *tables) { | |
| 303 | 533598 | Rpl_filter *rpl_filter = thd->rli_slave->rpl_filter; | |
| 304 | |||
| 305 |
6/6✓ Branch 0 taken 1554 times.
✓ Branch 1 taken 531895 times.
✓ Branch 2 taken 755 times.
✓ Branch 3 taken 799 times.
✓ Branch 4 taken 752 times.
✓ Branch 5 taken 3 times.
|
534391 | return rpl_filter->is_on() && tables && !thd->sp_runtime_ctx && |
| 306 |
2/2✓ Branch 0 taken 321 times.
✓ Branch 1 taken 472 times.
|
534242 | !rpl_filter->tables_ok(thd->db().str, tables); |
| 307 | } | ||
| 308 | |||
| 309 | /** | ||
| 310 | Checks whether the event for the given database, db, should | ||
| 311 | be ignored or not. This is done by checking whether there are | ||
| 312 | active rules in ignore_db or in do_db containers. If there | ||
| 313 | are, then check if there is a match, if not then check the | ||
| 314 | wild_do rules. | ||
| 315 | |||
| 316 | NOTE: This means that when using this function replicate-do-db | ||
| 317 | and replicate-ignore-db take precedence over wild do | ||
| 318 | rules. | ||
| 319 | |||
| 320 | @param thd Thread handle. | ||
| 321 | @param db Database name used while evaluating the filtering | ||
| 322 | rules. | ||
| 323 | @param sql_cmd Represents the current query that needs to be | ||
| 324 | verified against the database filter rules. | ||
| 325 | @return true Query should not be filtered out from the execution. | ||
| 326 | false Query should be filtered out from the execution. | ||
| 327 | |||
| 328 | */ | ||
| 329 | 536030 | inline bool check_database_filters(THD *thd, const char *db, | |
| 330 | enum_sql_command sql_cmd) { | ||
| 331 |
1/2✓ Branch 0 taken 536780 times.
✗ Branch 1 not taken.
|
536030 | DBUG_TRACE; |
| 332 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 536780 times.
|
536780 | assert(thd->slave_thread); |
| 333 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 536769 times.
|
536780 | if (!db) return true; |
| 334 | 536769 | Rpl_filter *rpl_filter = thd->rli_slave->rpl_filter; | |
| 335 | |||
| 336 | 536769 | bool need_increase_counter = true; | |
| 337 |
3/3✓ Branch 0 taken 349002 times.
✓ Branch 1 taken 1008 times.
✓ Branch 2 taken 186759 times.
|
536769 | switch (sql_cmd) { |
| 338 | 349002 | case SQLCOM_BEGIN: | |
| 339 | case SQLCOM_COMMIT: | ||
| 340 | case SQLCOM_SAVEPOINT: | ||
| 341 | case SQLCOM_ROLLBACK: | ||
| 342 | case SQLCOM_ROLLBACK_TO_SAVEPOINT: | ||
| 343 | 349002 | return true; | |
| 344 | 1008 | case SQLCOM_XA_START: | |
| 345 | case SQLCOM_XA_END: | ||
| 346 | case SQLCOM_XA_COMMIT: | ||
| 347 | case SQLCOM_XA_ROLLBACK: | ||
| 348 | 1008 | need_increase_counter = false; | |
| 349 | 187767 | default: | |
| 350 | 187767 | break; | |
| 351 | } | ||
| 352 | |||
| 353 |
1/2✓ Branch 0 taken 187399 times.
✗ Branch 1 not taken.
|
187767 | bool db_ok = rpl_filter->db_ok(db, need_increase_counter); |
| 354 | /* | ||
| 355 | No filters exist in ignore/do_db ? Then, just check | ||
| 356 | wild_do_table filtering for 'DATABASE' related | ||
| 357 | statements (CREATE/DROP/ATLER DATABASE) | ||
| 358 | */ | ||
| 359 |
9/10✓ Branch 0 taken 187132 times.
✓ Branch 1 taken 267 times.
✓ Branch 2 taken 187154 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 186762 times.
✓ Branch 5 taken 419 times.
✓ Branch 6 taken 186813 times.
✓ Branch 7 taken 57 times.
✓ Branch 8 taken 186829 times.
✓ Branch 9 taken 727 times.
|
374269 | if (db_ok && (rpl_filter->get_do_db()->is_empty() && |
| 360 |
1/2✓ Branch 0 taken 186726 times.
✗ Branch 1 not taken.
|
186762 | rpl_filter->get_ignore_db()->is_empty())) { |
| 361 |
2/2✓ Branch 0 taken 1630 times.
✓ Branch 1 taken 185199 times.
|
186829 | switch (sql_cmd) { |
| 362 | 1630 | case SQLCOM_CREATE_DB: | |
| 363 | case SQLCOM_ALTER_DB: | ||
| 364 | case SQLCOM_DROP_DB: | ||
| 365 |
1/2✓ Branch 0 taken 1630 times.
✗ Branch 1 not taken.
|
1630 | db_ok = rpl_filter->db_ok_with_wild_table(db); |
| 366 | 186829 | default: | |
| 367 | 186829 | break; | |
| 368 | } | ||
| 369 | } | ||
| 370 | 187556 | return db_ok; | |
| 371 | 536569 | } | |
| 372 | |||
| 373 | 162 | bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables) { | |
| 374 |
2/2✓ Branch 0 taken 180 times.
✓ Branch 1 taken 88 times.
|
268 | for (TABLE_LIST *table = tables; table; table = table->next_global) { |
| 375 |
2/4✓ Branch 0 taken 180 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 180 times.
✗ Branch 3 not taken.
|
180 | assert(table->db && table->table_name); |
| 376 | /* | ||
| 377 | Update on performance_schema and temp tables are allowed | ||
| 378 | in readonly mode. | ||
| 379 | */ | ||
| 380 |
2/2✓ Branch 0 taken 102 times.
✓ Branch 1 taken 58 times.
|
160 | if (table->updating && !find_temporary_table(thd, table) && |
| 381 | #ifdef WITH_WSREP | ||
| 382 |
2/2✓ Branch 0 taken 82 times.
✓ Branch 1 taken 20 times.
|
102 | !is_wsrep_system_table(table->db, table->db_length, table->table_name, |
| 383 |
4/4✓ Branch 0 taken 160 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 106 times.
|
340 | table->table_name_length) && |
| 384 | #endif /* WITH_WSREP */ | ||
| 385 |
2/2✓ Branch 0 taken 74 times.
✓ Branch 1 taken 8 times.
|
82 | !is_perfschema_db(table->db, table->db_length)) |
| 386 | 74 | return true; | |
| 387 | } | ||
| 388 | 88 | return false; | |
| 389 | } | ||
| 390 | |||
| 391 | /** | ||
| 392 | Returns whether the command in thd->lex->sql_command should cause an | ||
| 393 | implicit commit. An active transaction should be implicitly committed if the | ||
| 394 | statement requires so. | ||
| 395 | |||
| 396 | @param thd Thread handle. | ||
| 397 | @param mask Bitmask used for the SQL command match. | ||
| 398 | |||
| 399 | @retval true This statement shall cause an implicit commit. | ||
| 400 | @retval false This statement shall not cause an implicit commit. | ||
| 401 | */ | ||
| 402 | 86165711 | bool stmt_causes_implicit_commit(const THD *thd, uint mask) { | |
| 403 |
1/2✓ Branch 0 taken 86169627 times.
✗ Branch 1 not taken.
|
86165711 | DBUG_TRACE; |
| 404 | 86169627 | const LEX *lex = thd->lex; | |
| 405 | |||
| 406 |
6/6✓ Branch 0 taken 11686031 times.
✓ Branch 1 taken 74483596 times.
✓ Branch 2 taken 59782 times.
✓ Branch 3 taken 11626202 times.
✓ Branch 4 taken 74543352 times.
✓ Branch 5 taken 11626228 times.
|
97855611 | if ((sql_command_flags[lex->sql_command] & mask) == 0 || |
| 407 | 11686031 | thd->is_plugin_fake_ddl()) | |
| 408 | 74543352 | return false; | |
| 409 | |||
| 410 |
6/6✓ Branch 0 taken 710879 times.
✓ Branch 1 taken 2884664 times.
✓ Branch 2 taken 6011712 times.
✓ Branch 3 taken 101080 times.
✓ Branch 4 taken 4089 times.
✓ Branch 5 taken 1913804 times.
|
11626228 | switch (lex->sql_command) { |
| 411 | 710879 | case SQLCOM_DROP_TABLE: | |
| 412 | 710879 | return !lex->drop_temporary; | |
| 413 | 2884664 | case SQLCOM_ALTER_TABLE: | |
| 414 | case SQLCOM_CREATE_TABLE: | ||
| 415 | /* If CREATE TABLE of non-temporary table or without | ||
| 416 | START TRANSACTION, do implicit commit */ | ||
| 417 |
2/2✓ Branch 0 taken 2694016 times.
✓ Branch 1 taken 190648 times.
|
5578680 | return (lex->create_info->options & HA_LEX_CREATE_TMP_TABLE || |
| 418 |
2/2✓ Branch 0 taken 271 times.
✓ Branch 1 taken 2693745 times.
|
5578680 | lex->create_info->m_transactional_ddl) == 0; |
| 419 | 6011712 | case SQLCOM_SET_OPTION: | |
| 420 | /* Implicitly commit a transaction started by a SET statement */ | ||
| 421 | 6011712 | return lex->autocommit; | |
| 422 | 101080 | case SQLCOM_RESET: | |
| 423 | 101080 | return lex->option_type != OPT_PERSIST; | |
| 424 | 4089 | case SQLCOM_STOP_GROUP_REPLICATION: | |
| 425 | 4089 | return lex->was_replication_command_executed(); | |
| 426 | 1913804 | default: | |
| 427 | 1913804 | return true; | |
| 428 | } | ||
| 429 | 86169580 | } | |
| 430 | |||
| 431 | /** | ||
| 432 | Mark all commands that somehow changes a table. | ||
| 433 | |||
| 434 | This is used to check number of updates / hour. | ||
| 435 | |||
| 436 | sql_command is actually set to SQLCOM_END sometimes | ||
| 437 | so we need the +1 to include it in the array. | ||
| 438 | |||
| 439 | See COMMAND_FLAG_xxx for different type of commands | ||
| 440 | 2 - query that returns meaningful ROW_COUNT() - | ||
| 441 | a number of modified rows | ||
| 442 | */ | ||
| 443 | |||
| 444 | uint sql_command_flags[SQLCOM_END + 1]; | ||
| 445 | uint server_command_flags[COM_END + 1]; | ||
| 446 | |||
| 447 | 9736 | void init_sql_command_flags() { | |
| 448 | /* Initialize the server command flags array. */ | ||
| 449 | 9736 | memset(server_command_flags, 0, sizeof(server_command_flags)); | |
| 450 | |||
| 451 | 9736 | server_command_flags[COM_SLEEP] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 452 | 9736 | server_command_flags[COM_INIT_DB] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 453 | 9736 | server_command_flags[COM_QUERY] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 454 | 9736 | server_command_flags[COM_FIELD_LIST] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 455 | 9736 | server_command_flags[COM_REFRESH] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 456 | 9736 | server_command_flags[COM_STATISTICS] = CF_SKIP_QUESTIONS; | |
| 457 | 9736 | server_command_flags[COM_PROCESS_KILL] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 458 | 9736 | server_command_flags[COM_PING] = CF_SKIP_QUESTIONS; | |
| 459 | 9736 | server_command_flags[COM_STMT_PREPARE] = | |
| 460 | CF_SKIP_QUESTIONS | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 461 | 9736 | server_command_flags[COM_STMT_EXECUTE] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 462 | 9736 | server_command_flags[COM_STMT_SEND_LONG_DATA] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 463 | 9736 | server_command_flags[COM_STMT_CLOSE] = | |
| 464 | CF_SKIP_QUESTIONS | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 465 | 9736 | server_command_flags[COM_STMT_RESET] = | |
| 466 | CF_SKIP_QUESTIONS | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 467 | 9736 | server_command_flags[COM_STMT_FETCH] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 468 | 9736 | server_command_flags[COM_RESET_CONNECTION] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 469 | 9736 | server_command_flags[COM_END] = CF_ALLOW_PROTOCOL_PLUGIN; | |
| 470 | |||
| 471 | #ifdef WITH_WSREP | ||
| 472 | 9736 | server_command_flags[COM_STATISTICS] |= CF_SKIP_WSREP_CHECK; | |
| 473 | 9736 | server_command_flags[COM_PING] |= CF_SKIP_WSREP_CHECK; | |
| 474 | 9736 | server_command_flags[COM_STMT_PREPARE] |= CF_SKIP_WSREP_CHECK; | |
| 475 | 9736 | server_command_flags[COM_STMT_EXECUTE] |= CF_SKIP_WSREP_CHECK; | |
| 476 | 9736 | server_command_flags[COM_STMT_FETCH] |= CF_SKIP_WSREP_CHECK; | |
| 477 | 9736 | server_command_flags[COM_STMT_CLOSE] |= CF_SKIP_WSREP_CHECK; | |
| 478 | 9736 | server_command_flags[COM_STMT_RESET] |= CF_SKIP_WSREP_CHECK; | |
| 479 | 9736 | server_command_flags[COM_STMT_SEND_LONG_DATA] |= CF_SKIP_WSREP_CHECK; | |
| 480 | 9736 | server_command_flags[COM_QUIT] |= CF_SKIP_WSREP_CHECK; | |
| 481 | 9736 | server_command_flags[COM_PROCESS_INFO] |= CF_SKIP_WSREP_CHECK; | |
| 482 | 9736 | server_command_flags[COM_PROCESS_KILL] |= CF_SKIP_WSREP_CHECK; | |
| 483 | 9736 | server_command_flags[COM_SLEEP] |= CF_SKIP_WSREP_CHECK; | |
| 484 | 9736 | server_command_flags[COM_TIME] |= CF_SKIP_WSREP_CHECK; | |
| 485 | 9736 | server_command_flags[COM_INIT_DB] |= CF_SKIP_WSREP_CHECK; | |
| 486 | 9736 | server_command_flags[COM_END] |= CF_SKIP_WSREP_CHECK; | |
| 487 | 9736 | server_command_flags[COM_FIELD_LIST] |= CF_SKIP_WSREP_CHECK; | |
| 488 | |||
| 489 | /* | ||
| 490 | COM_QUERY and COM_SET_OPTION are allowed to pass the early COM_xxx filter, | ||
| 491 | they're checked later in mysql_execute_command(). | ||
| 492 | */ | ||
| 493 | 9736 | server_command_flags[COM_QUERY] |= CF_SKIP_WSREP_CHECK; | |
| 494 | 9736 | server_command_flags[COM_SET_OPTION] |= CF_SKIP_WSREP_CHECK; | |
| 495 | #endif /* WITH_WSREP */ | ||
| 496 | |||
| 497 | /* Initialize the sql command flags array. */ | ||
| 498 | 9736 | memset(sql_command_flags, 0, sizeof(sql_command_flags)); | |
| 499 | |||
| 500 | /* | ||
| 501 | In general, DDL statements do not generate row events and do not go | ||
| 502 | through a cache before being written to the binary log. However, the | ||
| 503 | CREATE TABLE...SELECT is an exception because it may generate row | ||
| 504 | events. For that reason, the SQLCOM_CREATE_TABLE which represents | ||
| 505 | a CREATE TABLE, including the CREATE TABLE...SELECT, has the | ||
| 506 | CF_CAN_GENERATE_ROW_EVENTS flag. The distinction between a regular | ||
| 507 | CREATE TABLE and the CREATE TABLE...SELECT is made in other parts of | ||
| 508 | the code, in particular in the Query_log_event's constructor. | ||
| 509 | */ | ||
| 510 | 9736 | sql_command_flags[SQLCOM_CREATE_TABLE] = | |
| 511 | CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS | | ||
| 512 | CF_CAN_GENERATE_ROW_EVENTS; | ||
| 513 | 9736 | sql_command_flags[SQLCOM_CREATE_INDEX] = | |
| 514 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 515 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLE] = | |
| 516 | CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS; | ||
| 517 | 9736 | sql_command_flags[SQLCOM_TRUNCATE] = | |
| 518 | CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS; | ||
| 519 | 9736 | sql_command_flags[SQLCOM_DROP_TABLE] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | |
| 520 | 9736 | sql_command_flags[SQLCOM_LOAD] = | |
| 521 | CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS; | ||
| 522 | 9736 | sql_command_flags[SQLCOM_CREATE_DB] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | |
| 523 | 9736 | sql_command_flags[SQLCOM_DROP_DB] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | |
| 524 | 9736 | sql_command_flags[SQLCOM_ALTER_DB] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | |
| 525 | 9736 | sql_command_flags[SQLCOM_RENAME_TABLE] = | |
| 526 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 527 | 9736 | sql_command_flags[SQLCOM_DROP_INDEX] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | |
| 528 | 9736 | sql_command_flags[SQLCOM_CREATE_VIEW] = | |
| 529 | CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS; | ||
| 530 | 9736 | sql_command_flags[SQLCOM_DROP_VIEW] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | |
| 531 | 9736 | sql_command_flags[SQLCOM_CREATE_TRIGGER] = | |
| 532 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 533 | 9736 | sql_command_flags[SQLCOM_DROP_TRIGGER] = | |
| 534 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 535 | 9736 | sql_command_flags[SQLCOM_CREATE_EVENT] = | |
| 536 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 537 | 9736 | sql_command_flags[SQLCOM_ALTER_EVENT] = | |
| 538 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 539 | 9736 | sql_command_flags[SQLCOM_DROP_EVENT] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | |
| 540 | 9736 | sql_command_flags[SQLCOM_IMPORT] = CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | |
| 541 | |||
| 542 | 9736 | sql_command_flags[SQLCOM_UPDATE] = CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | | |
| 543 | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 544 | CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED; | ||
| 545 | 9736 | sql_command_flags[SQLCOM_CREATE_COMPRESSION_DICTIONARY] = | |
| 546 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 547 | 9736 | sql_command_flags[SQLCOM_DROP_COMPRESSION_DICTIONARY] = | |
| 548 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 549 | 9736 | sql_command_flags[SQLCOM_UPDATE_MULTI] = | |
| 550 | CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 551 | CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED; | ||
| 552 | // This is INSERT VALUES(...), can be VALUES(stored_func()) so we trace it | ||
| 553 | 9736 | sql_command_flags[SQLCOM_INSERT] = CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | | |
| 554 | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 555 | CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED; | ||
| 556 | 9736 | sql_command_flags[SQLCOM_INSERT_SELECT] = | |
| 557 | CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 558 | CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED; | ||
| 559 | 9736 | sql_command_flags[SQLCOM_DELETE] = CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | | |
| 560 | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 561 | CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED; | ||
| 562 | 9736 | sql_command_flags[SQLCOM_DELETE_MULTI] = | |
| 563 | CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 564 | CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED; | ||
| 565 | 9736 | sql_command_flags[SQLCOM_REPLACE] = CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | | |
| 566 | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 567 | CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED; | ||
| 568 | 9736 | sql_command_flags[SQLCOM_REPLACE_SELECT] = | |
| 569 | CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 570 | CF_OPTIMIZER_TRACE | CF_CAN_BE_EXPLAINED; | ||
| 571 | 9736 | sql_command_flags[SQLCOM_SELECT] = | |
| 572 | CF_REEXECUTION_FRAGILE | CF_CAN_GENERATE_ROW_EVENTS | CF_OPTIMIZER_TRACE | | ||
| 573 | CF_HAS_RESULT_SET | CF_CAN_BE_EXPLAINED; | ||
| 574 | // (1) so that subquery is traced when doing "SET @var = (subquery)" | ||
| 575 | /* | ||
| 576 | @todo SQLCOM_SET_OPTION should have CF_CAN_GENERATE_ROW_EVENTS | ||
| 577 | set, because it may invoke a stored function that generates row | ||
| 578 | events. /Sven | ||
| 579 | */ | ||
| 580 | 9736 | sql_command_flags[SQLCOM_SET_OPTION] = | |
| 581 | CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS | | ||
| 582 | CF_CAN_GENERATE_ROW_EVENTS | CF_OPTIMIZER_TRACE; // (1) | ||
| 583 | // (1) so that subquery is traced when doing "DO @var := (subquery)" | ||
| 584 | 9736 | sql_command_flags[SQLCOM_DO] = CF_REEXECUTION_FRAGILE | | |
| 585 | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 586 | CF_OPTIMIZER_TRACE; // (1) | ||
| 587 | |||
| 588 | 9736 | sql_command_flags[SQLCOM_SET_PASSWORD] = | |
| 589 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_NEEDS_AUTOCOMMIT_OFF | | ||
| 590 | CF_POTENTIAL_ATOMIC_DDL | CF_DISALLOW_IN_RO_TRANS; | ||
| 591 | |||
| 592 | 9736 | sql_command_flags[SQLCOM_SHOW_STATUS_PROC] = | |
| 593 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 594 | 9736 | sql_command_flags[SQLCOM_SHOW_STATUS] = | |
| 595 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 596 | 9736 | sql_command_flags[SQLCOM_SHOW_DATABASES] = | |
| 597 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 598 | 9736 | sql_command_flags[SQLCOM_SHOW_TRIGGERS] = | |
| 599 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 600 | 9736 | sql_command_flags[SQLCOM_SHOW_EVENTS] = | |
| 601 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 602 | 9736 | sql_command_flags[SQLCOM_SHOW_OPEN_TABLES] = | |
| 603 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 604 | 9736 | sql_command_flags[SQLCOM_SHOW_PLUGINS] = CF_STATUS_COMMAND; | |
| 605 | 9736 | sql_command_flags[SQLCOM_SHOW_FIELDS] = | |
| 606 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 607 | 9736 | sql_command_flags[SQLCOM_SHOW_KEYS] = | |
| 608 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 609 | 9736 | sql_command_flags[SQLCOM_SHOW_VARIABLES] = | |
| 610 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 611 | 9736 | sql_command_flags[SQLCOM_SHOW_CHARSETS] = | |
| 612 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 613 | 9736 | sql_command_flags[SQLCOM_SHOW_COLLATIONS] = | |
| 614 | CF_STATUS_COMMAND | CF_HAS_RESULT_SET | CF_REEXECUTION_FRAGILE; | ||
| 615 | 9736 | sql_command_flags[SQLCOM_SHOW_BINLOGS] = CF_STATUS_COMMAND; | |
| 616 | 9736 | sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS] = CF_STATUS_COMMAND; | |
| 617 | 9736 | sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS] = CF_STATUS_COMMAND; | |
| 618 | 9736 | sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES] = CF_STATUS_COMMAND; | |
| 619 | 9736 | sql_command_flags[SQLCOM_SHOW_PRIVILEGES] = CF_STATUS_COMMAND; | |
| 620 | 9736 | sql_command_flags[SQLCOM_SHOW_WARNS] = CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT; | |
| 621 | 9736 | sql_command_flags[SQLCOM_SHOW_ERRORS] = | |
| 622 | CF_STATUS_COMMAND | CF_DIAGNOSTIC_STMT; | ||
| 623 | 9736 | sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS] = CF_STATUS_COMMAND; | |
| 624 | 9736 | sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX] = CF_STATUS_COMMAND; | |
| 625 | 9736 | sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS] = CF_STATUS_COMMAND; | |
| 626 | 9736 | sql_command_flags[SQLCOM_SHOW_PROCESSLIST] = CF_STATUS_COMMAND; | |
| 627 | 9736 | sql_command_flags[SQLCOM_SHOW_GRANTS] = CF_STATUS_COMMAND; | |
| 628 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_DB] = CF_STATUS_COMMAND; | |
| 629 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE] = CF_STATUS_COMMAND; | |
| 630 | 9736 | sql_command_flags[SQLCOM_SHOW_MASTER_STAT] = CF_STATUS_COMMAND; | |
| 631 | 9736 | sql_command_flags[SQLCOM_SHOW_SLAVE_STAT] = CF_STATUS_COMMAND; | |
| 632 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_PROC] = CF_STATUS_COMMAND; | |
| 633 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_FUNC] = CF_STATUS_COMMAND; | |
| 634 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER] = CF_STATUS_COMMAND; | |
| 635 | 9736 | sql_command_flags[SQLCOM_SHOW_STATUS_FUNC] = | |
| 636 | CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE | CF_HAS_RESULT_SET; | ||
| 637 | 9736 | sql_command_flags[SQLCOM_SHOW_PROC_CODE] = CF_STATUS_COMMAND; | |
| 638 | 9736 | sql_command_flags[SQLCOM_SHOW_FUNC_CODE] = CF_STATUS_COMMAND; | |
| 639 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_EVENT] = CF_STATUS_COMMAND; | |
| 640 | 9736 | sql_command_flags[SQLCOM_SHOW_PROFILES] = CF_STATUS_COMMAND; | |
| 641 | 9736 | sql_command_flags[SQLCOM_SHOW_PROFILE] = CF_STATUS_COMMAND; | |
| 642 | 9736 | sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT] = | |
| 643 | CF_STATUS_COMMAND | CF_CAN_GENERATE_ROW_EVENTS; | ||
| 644 | |||
| 645 | 9736 | sql_command_flags[SQLCOM_SHOW_TABLES] = | |
| 646 | (CF_STATUS_COMMAND | CF_SHOW_TABLE_COMMAND | CF_HAS_RESULT_SET | | ||
| 647 | CF_REEXECUTION_FRAGILE); | ||
| 648 | 9736 | sql_command_flags[SQLCOM_SHOW_TABLE_STATUS] = | |
| 649 | (CF_STATUS_COMMAND | CF_SHOW_TABLE_COMMAND | CF_HAS_RESULT_SET | | ||
| 650 | CF_REEXECUTION_FRAGILE); | ||
| 651 | 9736 | sql_command_flags[SQLCOM_SHOW_USER_STATS] = CF_STATUS_COMMAND; | |
| 652 | 9736 | sql_command_flags[SQLCOM_SHOW_TABLE_STATS] = CF_STATUS_COMMAND; | |
| 653 | 9736 | sql_command_flags[SQLCOM_SHOW_INDEX_STATS] = CF_STATUS_COMMAND; | |
| 654 | 9736 | sql_command_flags[SQLCOM_SHOW_CLIENT_STATS] = CF_STATUS_COMMAND; | |
| 655 | 9736 | sql_command_flags[SQLCOM_SHOW_THREAD_STATS] = CF_STATUS_COMMAND; | |
| 656 | /** | ||
| 657 | ACL DDLs do not access data-dictionary tables. However, they still | ||
| 658 | need to be marked to avoid autocommit. This is necessary because | ||
| 659 | code which saves GTID state or slave state in the system tables | ||
| 660 | at commit time does statement commit on low-level (see | ||
| 661 | System_table_access::close_table()) and thus can pre-maturely commit | ||
| 662 | DDL otherwise. | ||
| 663 | */ | ||
| 664 | 9736 | sql_command_flags[SQLCOM_CREATE_USER] = | |
| 665 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 666 | 9736 | sql_command_flags[SQLCOM_RENAME_USER] = | |
| 667 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 668 | 9736 | sql_command_flags[SQLCOM_DROP_USER] = | |
| 669 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 670 | 9736 | sql_command_flags[SQLCOM_ALTER_USER] = | |
| 671 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 672 | 9736 | sql_command_flags[SQLCOM_GRANT] = | |
| 673 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 674 | 9736 | sql_command_flags[SQLCOM_REVOKE] = | |
| 675 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 676 | 9736 | sql_command_flags[SQLCOM_REVOKE_ALL] = | |
| 677 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 678 | 9736 | sql_command_flags[SQLCOM_ALTER_USER_DEFAULT_ROLE] = | |
| 679 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 680 | 9736 | sql_command_flags[SQLCOM_GRANT_ROLE] = | |
| 681 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 682 | 9736 | sql_command_flags[SQLCOM_REVOKE_ROLE] = | |
| 683 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 684 | 9736 | sql_command_flags[SQLCOM_DROP_ROLE] = | |
| 685 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 686 | 9736 | sql_command_flags[SQLCOM_CREATE_ROLE] = | |
| 687 | CF_CHANGES_DATA | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 688 | |||
| 689 | 9736 | sql_command_flags[SQLCOM_OPTIMIZE] = CF_CHANGES_DATA; | |
| 690 | 9736 | sql_command_flags[SQLCOM_ALTER_INSTANCE] = CF_CHANGES_DATA; | |
| 691 | 9736 | sql_command_flags[SQLCOM_CREATE_FUNCTION] = | |
| 692 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 693 | 9736 | sql_command_flags[SQLCOM_CREATE_PROCEDURE] = | |
| 694 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 695 | 9736 | sql_command_flags[SQLCOM_CREATE_SPFUNCTION] = | |
| 696 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 697 | 9736 | sql_command_flags[SQLCOM_DROP_PROCEDURE] = | |
| 698 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 699 | 9736 | sql_command_flags[SQLCOM_DROP_FUNCTION] = | |
| 700 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 701 | 9736 | sql_command_flags[SQLCOM_ALTER_PROCEDURE] = | |
| 702 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 703 | 9736 | sql_command_flags[SQLCOM_ALTER_FUNCTION] = | |
| 704 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 705 | 9736 | sql_command_flags[SQLCOM_INSTALL_PLUGIN] = | |
| 706 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 707 | 9736 | sql_command_flags[SQLCOM_UNINSTALL_PLUGIN] = | |
| 708 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 709 | 9736 | sql_command_flags[SQLCOM_INSTALL_COMPONENT] = | |
| 710 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 711 | 9736 | sql_command_flags[SQLCOM_UNINSTALL_COMPONENT] = | |
| 712 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS; | ||
| 713 | 9736 | sql_command_flags[SQLCOM_CREATE_RESOURCE_GROUP] = | |
| 714 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 715 | 9736 | sql_command_flags[SQLCOM_ALTER_RESOURCE_GROUP] = | |
| 716 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 717 | 9736 | sql_command_flags[SQLCOM_DROP_RESOURCE_GROUP] = | |
| 718 | CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 719 | 9736 | sql_command_flags[SQLCOM_SET_RESOURCE_GROUP] = | |
| 720 | CF_CHANGES_DATA | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 721 | |||
| 722 | 9736 | sql_command_flags[SQLCOM_CLONE] = | |
| 723 | CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 724 | |||
| 725 | /* Does not change the contents of the Diagnostics Area. */ | ||
| 726 | 9736 | sql_command_flags[SQLCOM_GET_DIAGNOSTICS] = CF_DIAGNOSTIC_STMT; | |
| 727 | |||
| 728 | /* | ||
| 729 | (1): without it, in "CALL some_proc((subq))", subquery would not be | ||
| 730 | traced. | ||
| 731 | */ | ||
| 732 | 9736 | sql_command_flags[SQLCOM_CALL] = CF_REEXECUTION_FRAGILE | | |
| 733 | CF_CAN_GENERATE_ROW_EVENTS | | ||
| 734 | CF_OPTIMIZER_TRACE; // (1) | ||
| 735 | 9736 | sql_command_flags[SQLCOM_EXECUTE] = CF_CAN_GENERATE_ROW_EVENTS; | |
| 736 | |||
| 737 | /* | ||
| 738 | The following admin table operations are allowed | ||
| 739 | on log tables. | ||
| 740 | */ | ||
| 741 | 9736 | sql_command_flags[SQLCOM_REPAIR] = | |
| 742 | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS; | ||
| 743 | 9736 | sql_command_flags[SQLCOM_OPTIMIZE] |= | |
| 744 | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS; | ||
| 745 | 9736 | sql_command_flags[SQLCOM_ANALYZE] = | |
| 746 | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS; | ||
| 747 | 9736 | sql_command_flags[SQLCOM_CHECK] = | |
| 748 | CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS; | ||
| 749 | |||
| 750 | 9736 | sql_command_flags[SQLCOM_CREATE_USER] |= CF_AUTO_COMMIT_TRANS; | |
| 751 | 9736 | sql_command_flags[SQLCOM_CREATE_ROLE] |= CF_AUTO_COMMIT_TRANS; | |
| 752 | 9736 | sql_command_flags[SQLCOM_DROP_USER] |= CF_AUTO_COMMIT_TRANS; | |
| 753 | 9736 | sql_command_flags[SQLCOM_DROP_ROLE] |= CF_AUTO_COMMIT_TRANS; | |
| 754 | 9736 | sql_command_flags[SQLCOM_RENAME_USER] |= CF_AUTO_COMMIT_TRANS; | |
| 755 | 9736 | sql_command_flags[SQLCOM_ALTER_USER] |= CF_AUTO_COMMIT_TRANS; | |
| 756 | 9736 | sql_command_flags[SQLCOM_RESTART_SERVER] = | |
| 757 | CF_AUTO_COMMIT_TRANS | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 758 | 9736 | sql_command_flags[SQLCOM_REVOKE] |= CF_AUTO_COMMIT_TRANS; | |
| 759 | 9736 | sql_command_flags[SQLCOM_REVOKE_ALL] |= CF_AUTO_COMMIT_TRANS; | |
| 760 | 9736 | sql_command_flags[SQLCOM_REVOKE_ROLE] |= CF_AUTO_COMMIT_TRANS; | |
| 761 | 9736 | sql_command_flags[SQLCOM_GRANT] |= CF_AUTO_COMMIT_TRANS; | |
| 762 | 9736 | sql_command_flags[SQLCOM_GRANT_ROLE] |= CF_AUTO_COMMIT_TRANS; | |
| 763 | 9736 | sql_command_flags[SQLCOM_ALTER_USER_DEFAULT_ROLE] |= CF_AUTO_COMMIT_TRANS; | |
| 764 | |||
| 765 | 9736 | sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE] = CF_AUTO_COMMIT_TRANS; | |
| 766 | 9736 | sql_command_flags[SQLCOM_PRELOAD_KEYS] = CF_AUTO_COMMIT_TRANS; | |
| 767 | 9736 | sql_command_flags[SQLCOM_ALTER_INSTANCE] |= CF_AUTO_COMMIT_TRANS; | |
| 768 | |||
| 769 | 9736 | sql_command_flags[SQLCOM_FLUSH] = CF_AUTO_COMMIT_TRANS; | |
| 770 | 9736 | sql_command_flags[SQLCOM_RESET] = CF_AUTO_COMMIT_TRANS; | |
| 771 | 9736 | sql_command_flags[SQLCOM_CREATE_SERVER] = CF_AUTO_COMMIT_TRANS; | |
| 772 | 9736 | sql_command_flags[SQLCOM_ALTER_SERVER] = CF_AUTO_COMMIT_TRANS; | |
| 773 | 9736 | sql_command_flags[SQLCOM_DROP_SERVER] = CF_AUTO_COMMIT_TRANS; | |
| 774 | 9736 | sql_command_flags[SQLCOM_CHANGE_MASTER] = CF_AUTO_COMMIT_TRANS; | |
| 775 | 9736 | sql_command_flags[SQLCOM_CHANGE_REPLICATION_FILTER] = CF_AUTO_COMMIT_TRANS; | |
| 776 | 9736 | sql_command_flags[SQLCOM_SLAVE_START] = CF_AUTO_COMMIT_TRANS; | |
| 777 | 9736 | sql_command_flags[SQLCOM_SLAVE_STOP] = CF_AUTO_COMMIT_TRANS; | |
| 778 | 9736 | sql_command_flags[SQLCOM_STOP_GROUP_REPLICATION] = CF_IMPLICIT_COMMIT_END; | |
| 779 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLESPACE] |= CF_AUTO_COMMIT_TRANS; | |
| 780 | 9736 | sql_command_flags[SQLCOM_CREATE_SRS] |= CF_AUTO_COMMIT_TRANS; | |
| 781 | 9736 | sql_command_flags[SQLCOM_DROP_SRS] |= CF_AUTO_COMMIT_TRANS; | |
| 782 | |||
| 783 | /* | ||
| 784 | The following statements can deal with temporary tables, | ||
| 785 | so temporary tables should be pre-opened for those statements to | ||
| 786 | simplify privilege checking. | ||
| 787 | |||
| 788 | There are other statements that deal with temporary tables and open | ||
| 789 | them, but which are not listed here. The thing is that the order of | ||
| 790 | pre-opening temporary tables for those statements is somewhat custom. | ||
| 791 | */ | ||
| 792 | 9736 | sql_command_flags[SQLCOM_CREATE_TABLE] |= CF_PREOPEN_TMP_TABLES; | |
| 793 | 9736 | sql_command_flags[SQLCOM_DROP_TABLE] |= CF_PREOPEN_TMP_TABLES; | |
| 794 | 9736 | sql_command_flags[SQLCOM_CREATE_INDEX] |= CF_PREOPEN_TMP_TABLES; | |
| 795 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_PREOPEN_TMP_TABLES; | |
| 796 | 9736 | sql_command_flags[SQLCOM_TRUNCATE] |= CF_PREOPEN_TMP_TABLES; | |
| 797 | 9736 | sql_command_flags[SQLCOM_LOAD] |= CF_PREOPEN_TMP_TABLES; | |
| 798 | 9736 | sql_command_flags[SQLCOM_DROP_INDEX] |= CF_PREOPEN_TMP_TABLES; | |
| 799 | 9736 | sql_command_flags[SQLCOM_UPDATE] |= CF_PREOPEN_TMP_TABLES; | |
| 800 | 9736 | sql_command_flags[SQLCOM_UPDATE_MULTI] |= CF_PREOPEN_TMP_TABLES; | |
| 801 | 9736 | sql_command_flags[SQLCOM_INSERT] |= CF_PREOPEN_TMP_TABLES; | |
| 802 | 9736 | sql_command_flags[SQLCOM_INSERT_SELECT] |= CF_PREOPEN_TMP_TABLES; | |
| 803 | 9736 | sql_command_flags[SQLCOM_DELETE] |= CF_PREOPEN_TMP_TABLES; | |
| 804 | 9736 | sql_command_flags[SQLCOM_DELETE_MULTI] |= CF_PREOPEN_TMP_TABLES; | |
| 805 | 9736 | sql_command_flags[SQLCOM_REPLACE] |= CF_PREOPEN_TMP_TABLES; | |
| 806 | 9736 | sql_command_flags[SQLCOM_REPLACE_SELECT] |= CF_PREOPEN_TMP_TABLES; | |
| 807 | 9736 | sql_command_flags[SQLCOM_SELECT] |= CF_PREOPEN_TMP_TABLES; | |
| 808 | 9736 | sql_command_flags[SQLCOM_SET_OPTION] |= CF_PREOPEN_TMP_TABLES; | |
| 809 | 9736 | sql_command_flags[SQLCOM_DO] |= CF_PREOPEN_TMP_TABLES; | |
| 810 | 9736 | sql_command_flags[SQLCOM_CALL] |= CF_PREOPEN_TMP_TABLES; | |
| 811 | 9736 | sql_command_flags[SQLCOM_CHECKSUM] |= CF_PREOPEN_TMP_TABLES; | |
| 812 | 9736 | sql_command_flags[SQLCOM_ANALYZE] |= CF_PREOPEN_TMP_TABLES; | |
| 813 | 9736 | sql_command_flags[SQLCOM_CHECK] |= CF_PREOPEN_TMP_TABLES; | |
| 814 | 9736 | sql_command_flags[SQLCOM_OPTIMIZE] |= CF_PREOPEN_TMP_TABLES; | |
| 815 | 9736 | sql_command_flags[SQLCOM_REPAIR] |= CF_PREOPEN_TMP_TABLES; | |
| 816 | 9736 | sql_command_flags[SQLCOM_PRELOAD_KEYS] |= CF_PREOPEN_TMP_TABLES; | |
| 817 | 9736 | sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE] |= CF_PREOPEN_TMP_TABLES; | |
| 818 | |||
| 819 | /* | ||
| 820 | DDL statements that should start with closing opened handlers. | ||
| 821 | |||
| 822 | We use this flag only for statements for which open HANDLERs | ||
| 823 | have to be closed before emporary tables are pre-opened. | ||
| 824 | */ | ||
| 825 | 9736 | sql_command_flags[SQLCOM_CREATE_TABLE] |= CF_HA_CLOSE; | |
| 826 | 9736 | sql_command_flags[SQLCOM_DROP_TABLE] |= CF_HA_CLOSE; | |
| 827 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_HA_CLOSE; | |
| 828 | 9736 | sql_command_flags[SQLCOM_TRUNCATE] |= CF_HA_CLOSE; | |
| 829 | 9736 | sql_command_flags[SQLCOM_REPAIR] |= CF_HA_CLOSE; | |
| 830 | 9736 | sql_command_flags[SQLCOM_OPTIMIZE] |= CF_HA_CLOSE; | |
| 831 | 9736 | sql_command_flags[SQLCOM_ANALYZE] |= CF_HA_CLOSE; | |
| 832 | 9736 | sql_command_flags[SQLCOM_CHECK] |= CF_HA_CLOSE; | |
| 833 | 9736 | sql_command_flags[SQLCOM_CREATE_INDEX] |= CF_HA_CLOSE; | |
| 834 | 9736 | sql_command_flags[SQLCOM_DROP_INDEX] |= CF_HA_CLOSE; | |
| 835 | 9736 | sql_command_flags[SQLCOM_PRELOAD_KEYS] |= CF_HA_CLOSE; | |
| 836 | 9736 | sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE] |= CF_HA_CLOSE; | |
| 837 | |||
| 838 | /* | ||
| 839 | Mark statements that always are disallowed in read-only | ||
| 840 | transactions. Note that according to the SQL standard, | ||
| 841 | even temporary table DDL should be disallowed. | ||
| 842 | */ | ||
| 843 | 9736 | sql_command_flags[SQLCOM_CREATE_TABLE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 844 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 845 | 9736 | sql_command_flags[SQLCOM_DROP_TABLE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 846 | 9736 | sql_command_flags[SQLCOM_RENAME_TABLE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 847 | 9736 | sql_command_flags[SQLCOM_CREATE_INDEX] |= CF_DISALLOW_IN_RO_TRANS; | |
| 848 | 9736 | sql_command_flags[SQLCOM_DROP_INDEX] |= CF_DISALLOW_IN_RO_TRANS; | |
| 849 | 9736 | sql_command_flags[SQLCOM_CREATE_DB] |= CF_DISALLOW_IN_RO_TRANS; | |
| 850 | 9736 | sql_command_flags[SQLCOM_DROP_DB] |= CF_DISALLOW_IN_RO_TRANS; | |
| 851 | 9736 | sql_command_flags[SQLCOM_ALTER_DB] |= CF_DISALLOW_IN_RO_TRANS; | |
| 852 | 9736 | sql_command_flags[SQLCOM_CREATE_VIEW] |= CF_DISALLOW_IN_RO_TRANS; | |
| 853 | 9736 | sql_command_flags[SQLCOM_DROP_VIEW] |= CF_DISALLOW_IN_RO_TRANS; | |
| 854 | 9736 | sql_command_flags[SQLCOM_CREATE_TRIGGER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 855 | 9736 | sql_command_flags[SQLCOM_DROP_TRIGGER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 856 | 9736 | sql_command_flags[SQLCOM_CREATE_EVENT] |= CF_DISALLOW_IN_RO_TRANS; | |
| 857 | 9736 | sql_command_flags[SQLCOM_ALTER_EVENT] |= CF_DISALLOW_IN_RO_TRANS; | |
| 858 | 9736 | sql_command_flags[SQLCOM_DROP_EVENT] |= CF_DISALLOW_IN_RO_TRANS; | |
| 859 | 9736 | sql_command_flags[SQLCOM_CREATE_USER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 860 | 9736 | sql_command_flags[SQLCOM_CREATE_ROLE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 861 | 9736 | sql_command_flags[SQLCOM_RENAME_USER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 862 | 9736 | sql_command_flags[SQLCOM_ALTER_USER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 863 | 9736 | sql_command_flags[SQLCOM_DROP_USER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 864 | 9736 | sql_command_flags[SQLCOM_DROP_ROLE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 865 | 9736 | sql_command_flags[SQLCOM_CREATE_SERVER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 866 | 9736 | sql_command_flags[SQLCOM_ALTER_SERVER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 867 | 9736 | sql_command_flags[SQLCOM_DROP_SERVER] |= CF_DISALLOW_IN_RO_TRANS; | |
| 868 | 9736 | sql_command_flags[SQLCOM_CREATE_FUNCTION] |= CF_DISALLOW_IN_RO_TRANS; | |
| 869 | 9736 | sql_command_flags[SQLCOM_CREATE_PROCEDURE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 870 | 9736 | sql_command_flags[SQLCOM_CREATE_SPFUNCTION] |= CF_DISALLOW_IN_RO_TRANS; | |
| 871 | 9736 | sql_command_flags[SQLCOM_DROP_PROCEDURE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 872 | 9736 | sql_command_flags[SQLCOM_DROP_FUNCTION] |= CF_DISALLOW_IN_RO_TRANS; | |
| 873 | 9736 | sql_command_flags[SQLCOM_ALTER_PROCEDURE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 874 | 9736 | sql_command_flags[SQLCOM_ALTER_FUNCTION] |= CF_DISALLOW_IN_RO_TRANS; | |
| 875 | 9736 | sql_command_flags[SQLCOM_TRUNCATE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 876 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLESPACE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 877 | 9736 | sql_command_flags[SQLCOM_REPAIR] |= CF_DISALLOW_IN_RO_TRANS; | |
| 878 | 9736 | sql_command_flags[SQLCOM_OPTIMIZE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 879 | 9736 | sql_command_flags[SQLCOM_GRANT] |= CF_DISALLOW_IN_RO_TRANS; | |
| 880 | 9736 | sql_command_flags[SQLCOM_GRANT_ROLE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 881 | 9736 | sql_command_flags[SQLCOM_REVOKE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 882 | 9736 | sql_command_flags[SQLCOM_REVOKE_ALL] |= CF_DISALLOW_IN_RO_TRANS; | |
| 883 | 9736 | sql_command_flags[SQLCOM_REVOKE_ROLE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 884 | 9736 | sql_command_flags[SQLCOM_INSTALL_PLUGIN] |= CF_DISALLOW_IN_RO_TRANS; | |
| 885 | 9736 | sql_command_flags[SQLCOM_UNINSTALL_PLUGIN] |= CF_DISALLOW_IN_RO_TRANS; | |
| 886 | 9736 | sql_command_flags[SQLCOM_INSTALL_COMPONENT] |= CF_DISALLOW_IN_RO_TRANS; | |
| 887 | 9736 | sql_command_flags[SQLCOM_UNINSTALL_COMPONENT] |= CF_DISALLOW_IN_RO_TRANS; | |
| 888 | 9736 | sql_command_flags[SQLCOM_ALTER_INSTANCE] |= CF_DISALLOW_IN_RO_TRANS; | |
| 889 | 9736 | sql_command_flags[SQLCOM_IMPORT] |= CF_DISALLOW_IN_RO_TRANS; | |
| 890 | 9736 | sql_command_flags[SQLCOM_CREATE_SRS] |= CF_DISALLOW_IN_RO_TRANS; | |
| 891 | 9736 | sql_command_flags[SQLCOM_DROP_SRS] |= CF_DISALLOW_IN_RO_TRANS; | |
| 892 | 9736 | sql_command_flags[SQLCOM_CREATE_COMPRESSION_DICTIONARY] |= | |
| 893 | CF_DISALLOW_IN_RO_TRANS; | ||
| 894 | 9736 | sql_command_flags[SQLCOM_DROP_COMPRESSION_DICTIONARY] |= | |
| 895 | CF_DISALLOW_IN_RO_TRANS; | ||
| 896 | |||
| 897 | /* | ||
| 898 | Mark statements that are allowed to be executed by the plugins. | ||
| 899 | */ | ||
| 900 | 9736 | sql_command_flags[SQLCOM_SELECT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 901 | 9736 | sql_command_flags[SQLCOM_CREATE_TABLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 902 | 9736 | sql_command_flags[SQLCOM_CREATE_INDEX] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 903 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 904 | 9736 | sql_command_flags[SQLCOM_UPDATE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 905 | 9736 | sql_command_flags[SQLCOM_INSERT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 906 | 9736 | sql_command_flags[SQLCOM_INSERT_SELECT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 907 | 9736 | sql_command_flags[SQLCOM_DELETE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 908 | 9736 | sql_command_flags[SQLCOM_TRUNCATE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 909 | 9736 | sql_command_flags[SQLCOM_DROP_TABLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 910 | 9736 | sql_command_flags[SQLCOM_DROP_INDEX] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 911 | 9736 | sql_command_flags[SQLCOM_SHOW_DATABASES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 912 | 9736 | sql_command_flags[SQLCOM_SHOW_TABLES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 913 | 9736 | sql_command_flags[SQLCOM_SHOW_FIELDS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 914 | 9736 | sql_command_flags[SQLCOM_SHOW_KEYS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 915 | 9736 | sql_command_flags[SQLCOM_SHOW_VARIABLES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 916 | 9736 | sql_command_flags[SQLCOM_SHOW_STATUS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 917 | 9736 | sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 918 | 9736 | sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 919 | 9736 | sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 920 | 9736 | sql_command_flags[SQLCOM_SHOW_PROCESSLIST] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 921 | 9736 | sql_command_flags[SQLCOM_SHOW_MASTER_STAT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 922 | 9736 | sql_command_flags[SQLCOM_SHOW_SLAVE_STAT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 923 | 9736 | sql_command_flags[SQLCOM_SHOW_GRANTS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 924 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 925 | 9736 | sql_command_flags[SQLCOM_SHOW_CHARSETS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 926 | 9736 | sql_command_flags[SQLCOM_SHOW_COLLATIONS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 927 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_DB] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 928 | 9736 | sql_command_flags[SQLCOM_SHOW_TABLE_STATUS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 929 | 9736 | sql_command_flags[SQLCOM_SHOW_TRIGGERS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 930 | 9736 | sql_command_flags[SQLCOM_LOAD] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 931 | 9736 | sql_command_flags[SQLCOM_SET_OPTION] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 932 | 9736 | sql_command_flags[SQLCOM_LOCK_TABLES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 933 | 9736 | sql_command_flags[SQLCOM_UNLOCK_TABLES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 934 | 9736 | sql_command_flags[SQLCOM_GRANT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 935 | 9736 | sql_command_flags[SQLCOM_CHANGE_DB] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 936 | 9736 | sql_command_flags[SQLCOM_CREATE_DB] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 937 | 9736 | sql_command_flags[SQLCOM_DROP_DB] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 938 | 9736 | sql_command_flags[SQLCOM_ALTER_DB] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 939 | 9736 | sql_command_flags[SQLCOM_REPAIR] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 940 | 9736 | sql_command_flags[SQLCOM_REPLACE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 941 | 9736 | sql_command_flags[SQLCOM_REPLACE_SELECT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 942 | 9736 | sql_command_flags[SQLCOM_CREATE_FUNCTION] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 943 | 9736 | sql_command_flags[SQLCOM_DROP_FUNCTION] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 944 | 9736 | sql_command_flags[SQLCOM_REVOKE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 945 | 9736 | sql_command_flags[SQLCOM_OPTIMIZE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 946 | 9736 | sql_command_flags[SQLCOM_CHECK] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 947 | 9736 | sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 948 | 9736 | sql_command_flags[SQLCOM_PRELOAD_KEYS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 949 | 9736 | sql_command_flags[SQLCOM_FLUSH] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 950 | 9736 | sql_command_flags[SQLCOM_KILL] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 951 | 9736 | sql_command_flags[SQLCOM_ANALYZE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 952 | 9736 | sql_command_flags[SQLCOM_ROLLBACK] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 953 | 9736 | sql_command_flags[SQLCOM_ROLLBACK_TO_SAVEPOINT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 954 | 9736 | sql_command_flags[SQLCOM_COMMIT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 955 | 9736 | sql_command_flags[SQLCOM_SAVEPOINT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 956 | 9736 | sql_command_flags[SQLCOM_RELEASE_SAVEPOINT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 957 | 9736 | sql_command_flags[SQLCOM_SLAVE_START] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 958 | 9736 | sql_command_flags[SQLCOM_SLAVE_STOP] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 959 | 9736 | sql_command_flags[SQLCOM_START_GROUP_REPLICATION] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 960 | 9736 | sql_command_flags[SQLCOM_STOP_GROUP_REPLICATION] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 961 | 9736 | sql_command_flags[SQLCOM_BEGIN] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 962 | 9736 | sql_command_flags[SQLCOM_CHANGE_MASTER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 963 | 9736 | sql_command_flags[SQLCOM_CHANGE_REPLICATION_FILTER] |= | |
| 964 | CF_ALLOW_PROTOCOL_PLUGIN; | ||
| 965 | 9736 | sql_command_flags[SQLCOM_RENAME_TABLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 966 | 9736 | sql_command_flags[SQLCOM_RESET] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 967 | 9736 | sql_command_flags[SQLCOM_PURGE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 968 | 9736 | sql_command_flags[SQLCOM_PURGE_BEFORE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 969 | 9736 | sql_command_flags[SQLCOM_SHOW_BINLOGS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 970 | 9736 | sql_command_flags[SQLCOM_SHOW_OPEN_TABLES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 971 | 9736 | sql_command_flags[SQLCOM_HA_OPEN] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 972 | 9736 | sql_command_flags[SQLCOM_HA_CLOSE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 973 | 9736 | sql_command_flags[SQLCOM_HA_READ] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 974 | 9736 | sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 975 | 9736 | sql_command_flags[SQLCOM_DELETE_MULTI] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 976 | 9736 | sql_command_flags[SQLCOM_UPDATE_MULTI] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 977 | 9736 | sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 978 | 9736 | sql_command_flags[SQLCOM_DO] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 979 | 9736 | sql_command_flags[SQLCOM_SHOW_WARNS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 980 | 9736 | sql_command_flags[SQLCOM_EMPTY_QUERY] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 981 | 9736 | sql_command_flags[SQLCOM_SHOW_ERRORS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 982 | 9736 | sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 983 | 9736 | sql_command_flags[SQLCOM_SHOW_PRIVILEGES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 984 | 9736 | sql_command_flags[SQLCOM_HELP] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 985 | 9736 | sql_command_flags[SQLCOM_CREATE_USER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 986 | 9736 | sql_command_flags[SQLCOM_DROP_USER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 987 | 9736 | sql_command_flags[SQLCOM_RENAME_USER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 988 | 9736 | sql_command_flags[SQLCOM_REVOKE_ALL] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 989 | 9736 | sql_command_flags[SQLCOM_CHECKSUM] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 990 | 9736 | sql_command_flags[SQLCOM_CREATE_PROCEDURE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 991 | 9736 | sql_command_flags[SQLCOM_CREATE_SPFUNCTION] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 992 | 9736 | sql_command_flags[SQLCOM_CALL] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 993 | 9736 | sql_command_flags[SQLCOM_DROP_PROCEDURE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 994 | 9736 | sql_command_flags[SQLCOM_ALTER_PROCEDURE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 995 | 9736 | sql_command_flags[SQLCOM_ALTER_FUNCTION] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 996 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_PROC] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 997 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_FUNC] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 998 | 9736 | sql_command_flags[SQLCOM_SHOW_STATUS_PROC] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 999 | 9736 | sql_command_flags[SQLCOM_SHOW_STATUS_FUNC] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1000 | 9736 | sql_command_flags[SQLCOM_PREPARE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1001 | 9736 | sql_command_flags[SQLCOM_EXECUTE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1002 | 9736 | sql_command_flags[SQLCOM_DEALLOCATE_PREPARE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1003 | 9736 | sql_command_flags[SQLCOM_CREATE_VIEW] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1004 | 9736 | sql_command_flags[SQLCOM_DROP_VIEW] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1005 | 9736 | sql_command_flags[SQLCOM_CREATE_TRIGGER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1006 | 9736 | sql_command_flags[SQLCOM_DROP_TRIGGER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1007 | 9736 | sql_command_flags[SQLCOM_XA_START] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1008 | 9736 | sql_command_flags[SQLCOM_XA_END] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1009 | 9736 | sql_command_flags[SQLCOM_XA_PREPARE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1010 | 9736 | sql_command_flags[SQLCOM_XA_COMMIT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1011 | 9736 | sql_command_flags[SQLCOM_XA_ROLLBACK] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1012 | 9736 | sql_command_flags[SQLCOM_XA_RECOVER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1013 | 9736 | sql_command_flags[SQLCOM_SHOW_PROC_CODE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1014 | 9736 | sql_command_flags[SQLCOM_SHOW_FUNC_CODE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1015 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLESPACE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1016 | 9736 | sql_command_flags[SQLCOM_BINLOG_BASE64_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1017 | 9736 | sql_command_flags[SQLCOM_SHOW_PLUGINS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1018 | 9736 | sql_command_flags[SQLCOM_CREATE_SERVER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1019 | 9736 | sql_command_flags[SQLCOM_DROP_SERVER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1020 | 9736 | sql_command_flags[SQLCOM_ALTER_SERVER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1021 | 9736 | sql_command_flags[SQLCOM_CREATE_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1022 | 9736 | sql_command_flags[SQLCOM_ALTER_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1023 | 9736 | sql_command_flags[SQLCOM_DROP_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1024 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_EVENT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1025 | 9736 | sql_command_flags[SQLCOM_SHOW_EVENTS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1026 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1027 | 9736 | sql_command_flags[SQLCOM_SHOW_PROFILE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1028 | 9736 | sql_command_flags[SQLCOM_SHOW_PROFILES] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1029 | 9736 | sql_command_flags[SQLCOM_SIGNAL] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1030 | 9736 | sql_command_flags[SQLCOM_RESIGNAL] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1031 | 9736 | sql_command_flags[SQLCOM_SHOW_RELAYLOG_EVENTS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1032 | 9736 | sql_command_flags[SQLCOM_GET_DIAGNOSTICS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1033 | 9736 | sql_command_flags[SQLCOM_ALTER_USER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1034 | 9736 | sql_command_flags[SQLCOM_EXPLAIN_OTHER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1035 | 9736 | sql_command_flags[SQLCOM_SHOW_CREATE_USER] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1036 | 9736 | sql_command_flags[SQLCOM_SET_PASSWORD] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1037 | 9736 | sql_command_flags[SQLCOM_DROP_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1038 | 9736 | sql_command_flags[SQLCOM_CREATE_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1039 | 9736 | sql_command_flags[SQLCOM_SET_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1040 | 9736 | sql_command_flags[SQLCOM_GRANT_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1041 | 9736 | sql_command_flags[SQLCOM_REVOKE_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1042 | 9736 | sql_command_flags[SQLCOM_ALTER_USER_DEFAULT_ROLE] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1043 | 9736 | sql_command_flags[SQLCOM_IMPORT] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1044 | 9736 | sql_command_flags[SQLCOM_END] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1045 | 9736 | sql_command_flags[SQLCOM_CREATE_SRS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1046 | 9736 | sql_command_flags[SQLCOM_DROP_SRS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1047 | 9736 | sql_command_flags[SQLCOM_SHOW_USER_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1048 | 9736 | sql_command_flags[SQLCOM_SHOW_TABLE_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1049 | 9736 | sql_command_flags[SQLCOM_SHOW_INDEX_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1050 | 9736 | sql_command_flags[SQLCOM_SHOW_CLIENT_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1051 | 9736 | sql_command_flags[SQLCOM_SHOW_THREAD_STATS] |= CF_ALLOW_PROTOCOL_PLUGIN; | |
| 1052 | |||
| 1053 | /* | ||
| 1054 | Mark DDL statements which require that auto-commit mode to be temporarily | ||
| 1055 | turned off. See sqlcom_needs_autocommit_off() for more details. | ||
| 1056 | |||
| 1057 | CREATE TABLE and DROP TABLE are not marked as such as they have special | ||
| 1058 | variants dealing with temporary tables which don't update data-dictionary | ||
| 1059 | at all and which should be allowed in the middle of transaction. | ||
| 1060 | */ | ||
| 1061 | 9736 | sql_command_flags[SQLCOM_CREATE_INDEX] |= | |
| 1062 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1063 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLE] |= | |
| 1064 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1065 | 9736 | sql_command_flags[SQLCOM_TRUNCATE] |= | |
| 1066 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1067 | 9736 | sql_command_flags[SQLCOM_DROP_INDEX] |= | |
| 1068 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1069 | 9736 | sql_command_flags[SQLCOM_CREATE_DB] |= | |
| 1070 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1071 | 9736 | sql_command_flags[SQLCOM_DROP_DB] |= | |
| 1072 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1073 | 9736 | sql_command_flags[SQLCOM_ALTER_DB] |= | |
| 1074 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1075 | 9736 | sql_command_flags[SQLCOM_REPAIR] |= CF_NEEDS_AUTOCOMMIT_OFF; | |
| 1076 | 9736 | sql_command_flags[SQLCOM_OPTIMIZE] |= CF_NEEDS_AUTOCOMMIT_OFF; | |
| 1077 | 9736 | sql_command_flags[SQLCOM_RENAME_TABLE] |= | |
| 1078 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1079 | 9736 | sql_command_flags[SQLCOM_CREATE_VIEW] |= | |
| 1080 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1081 | 9736 | sql_command_flags[SQLCOM_DROP_VIEW] |= | |
| 1082 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1083 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLESPACE] |= | |
| 1084 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1085 | 9736 | sql_command_flags[SQLCOM_CREATE_SPFUNCTION] |= | |
| 1086 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1087 | 9736 | sql_command_flags[SQLCOM_DROP_FUNCTION] |= | |
| 1088 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1089 | 9736 | sql_command_flags[SQLCOM_ALTER_FUNCTION] |= | |
| 1090 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1091 | 9736 | sql_command_flags[SQLCOM_CREATE_FUNCTION] |= | |
| 1092 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1093 | 9736 | sql_command_flags[SQLCOM_CREATE_PROCEDURE] |= | |
| 1094 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1095 | 9736 | sql_command_flags[SQLCOM_DROP_PROCEDURE] |= | |
| 1096 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1097 | 9736 | sql_command_flags[SQLCOM_ALTER_PROCEDURE] |= | |
| 1098 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1099 | 9736 | sql_command_flags[SQLCOM_CREATE_TRIGGER] |= | |
| 1100 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1101 | 9736 | sql_command_flags[SQLCOM_DROP_TRIGGER] |= | |
| 1102 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1103 | 9736 | sql_command_flags[SQLCOM_IMPORT] |= | |
| 1104 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1105 | 9736 | sql_command_flags[SQLCOM_INSTALL_PLUGIN] |= CF_NEEDS_AUTOCOMMIT_OFF; | |
| 1106 | 9736 | sql_command_flags[SQLCOM_UNINSTALL_PLUGIN] |= CF_NEEDS_AUTOCOMMIT_OFF; | |
| 1107 | 9736 | sql_command_flags[SQLCOM_CREATE_EVENT] |= | |
| 1108 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1109 | 9736 | sql_command_flags[SQLCOM_ALTER_EVENT] |= | |
| 1110 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1111 | 9736 | sql_command_flags[SQLCOM_DROP_EVENT] |= | |
| 1112 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1113 | 9736 | sql_command_flags[SQLCOM_CREATE_SRS] |= | |
| 1114 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1115 | 9736 | sql_command_flags[SQLCOM_DROP_SRS] |= | |
| 1116 | CF_NEEDS_AUTOCOMMIT_OFF | CF_POTENTIAL_ATOMIC_DDL; | ||
| 1117 | |||
| 1118 | /* | ||
| 1119 | Mark these statements as SHOW commands using INFORMATION_SCHEMA system | ||
| 1120 | views. | ||
| 1121 | */ | ||
| 1122 | 9736 | sql_command_flags[SQLCOM_SHOW_CHARSETS] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1123 | 9736 | sql_command_flags[SQLCOM_SHOW_COLLATIONS] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1124 | 9736 | sql_command_flags[SQLCOM_SHOW_DATABASES] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1125 | 9736 | sql_command_flags[SQLCOM_SHOW_TABLES] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1126 | 9736 | sql_command_flags[SQLCOM_SHOW_TABLE_STATUS] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1127 | 9736 | sql_command_flags[SQLCOM_SHOW_FIELDS] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1128 | 9736 | sql_command_flags[SQLCOM_SHOW_KEYS] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1129 | 9736 | sql_command_flags[SQLCOM_SHOW_EVENTS] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1130 | 9736 | sql_command_flags[SQLCOM_SHOW_TRIGGERS] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1131 | 9736 | sql_command_flags[SQLCOM_SHOW_STATUS_PROC] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1132 | 9736 | sql_command_flags[SQLCOM_SHOW_STATUS_FUNC] |= CF_SHOW_USES_SYSTEM_VIEW; | |
| 1133 | |||
| 1134 | /** | ||
| 1135 | Some statements doesn't if the ACL CACHE is disabled using the | ||
| 1136 | --skip-grant-tables server option. | ||
| 1137 | */ | ||
| 1138 | 9736 | sql_command_flags[SQLCOM_SET_ROLE] |= CF_REQUIRE_ACL_CACHE; | |
| 1139 | 9736 | sql_command_flags[SQLCOM_ALTER_USER_DEFAULT_ROLE] |= CF_REQUIRE_ACL_CACHE; | |
| 1140 | 9736 | sql_command_flags[SQLCOM_CREATE_ROLE] |= CF_REQUIRE_ACL_CACHE; | |
| 1141 | 9736 | sql_command_flags[SQLCOM_DROP_ROLE] |= CF_REQUIRE_ACL_CACHE; | |
| 1142 | 9736 | sql_command_flags[SQLCOM_GRANT_ROLE] |= CF_REQUIRE_ACL_CACHE; | |
| 1143 | 9736 | sql_command_flags[SQLCOM_ALTER_USER] |= CF_REQUIRE_ACL_CACHE; | |
| 1144 | 9736 | sql_command_flags[SQLCOM_GRANT] |= CF_REQUIRE_ACL_CACHE; | |
| 1145 | 9736 | sql_command_flags[SQLCOM_REVOKE] |= CF_REQUIRE_ACL_CACHE; | |
| 1146 | 9736 | sql_command_flags[SQLCOM_REVOKE_ALL] |= CF_REQUIRE_ACL_CACHE; | |
| 1147 | 9736 | sql_command_flags[SQLCOM_REVOKE_ROLE] |= CF_REQUIRE_ACL_CACHE; | |
| 1148 | 9736 | sql_command_flags[SQLCOM_CREATE_USER] |= CF_REQUIRE_ACL_CACHE; | |
| 1149 | 9736 | sql_command_flags[SQLCOM_DROP_USER] |= CF_REQUIRE_ACL_CACHE; | |
| 1150 | 9736 | sql_command_flags[SQLCOM_RENAME_USER] |= CF_REQUIRE_ACL_CACHE; | |
| 1151 | 9736 | sql_command_flags[SQLCOM_SHOW_GRANTS] |= CF_REQUIRE_ACL_CACHE; | |
| 1152 | 9736 | sql_command_flags[SQLCOM_SET_PASSWORD] |= CF_REQUIRE_ACL_CACHE; | |
| 1153 | |||
| 1154 | #ifdef WITH_WSREP | ||
| 1155 | /* | ||
| 1156 | Statements for which some errors are ignored when | ||
| 1157 | wsrep_ignore_apply_errors = WSREP_IGNORE_ERRORS_ON_RECONCILING_DDL | ||
| 1158 | */ | ||
| 1159 | 9736 | sql_command_flags[SQLCOM_DROP_DB] |= CF_WSREP_MAY_IGNORE_ERRORS; | |
| 1160 | 9736 | sql_command_flags[SQLCOM_DROP_TABLE] |= CF_WSREP_MAY_IGNORE_ERRORS; | |
| 1161 | 9736 | sql_command_flags[SQLCOM_DROP_INDEX] |= CF_WSREP_MAY_IGNORE_ERRORS; | |
| 1162 | 9736 | sql_command_flags[SQLCOM_ALTER_TABLE] |= CF_WSREP_MAY_IGNORE_ERRORS; | |
| 1163 | #endif /* WITH_WSREP */ | ||
| 1164 | 9736 | } | |
| 1165 | |||
| 1166 | 5612940 | bool sqlcom_can_generate_row_events(enum enum_sql_command command) { | |
| 1167 | 5612940 | return (sql_command_flags[command] & CF_CAN_GENERATE_ROW_EVENTS); | |
| 1168 | } | ||
| 1169 | |||
| 1170 | 6870162 | bool is_update_query(enum enum_sql_command command) { | |
| 1171 |
2/4✓ Branch 0 taken 6870334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6870531 times.
✗ Branch 3 not taken.
|
6870162 | assert(command >= 0 && command <= SQLCOM_END); |
| 1172 | 6870531 | return (sql_command_flags[command] & CF_CHANGES_DATA) != 0; | |
| 1173 | } | ||
| 1174 | |||
| 1175 | 21298250 | bool is_explainable_query(enum enum_sql_command command) { | |
| 1176 |
3/4✓ Branch 0 taken 21298418 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21298369 times.
✓ Branch 3 taken 49 times.
|
21298250 | assert(command >= 0 && command <= SQLCOM_END); |
| 1177 | 21298369 | return (sql_command_flags[command] & CF_CAN_BE_EXPLAINED) != 0; | |
| 1178 | } | ||
| 1179 | |||
| 1180 | /** | ||
| 1181 | Check if a sql command is allowed to write to log tables. | ||
| 1182 | @param command The SQL command | ||
| 1183 | @return true if writing is allowed | ||
| 1184 | */ | ||
| 1185 | 32522798 | bool is_log_table_write_query(enum enum_sql_command command) { | |
| 1186 |
2/4✓ Branch 0 taken 32522880 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32523000 times.
✗ Branch 3 not taken.
|
32522798 | assert(command >= 0 && command <= SQLCOM_END); |
| 1187 | 32523000 | return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0; | |
| 1188 | } | ||
| 1189 | |||
| 1190 | /** | ||
| 1191 | Check if statement (typically DDL) needs auto-commit mode temporarily | ||
| 1192 | turned off. | ||
| 1193 | |||
| 1194 | @note This is necessary to prevent InnoDB from automatically committing | ||
| 1195 | InnoDB transaction each time data-dictionary tables are closed | ||
| 1196 | after being updated. | ||
| 1197 | */ | ||
| 1198 | 21364332 | static bool sqlcom_needs_autocommit_off(const LEX *lex) { | |
| 1199 | 42312595 | return (sql_command_flags[lex->sql_command] & CF_NEEDS_AUTOCOMMIT_OFF) || | |
| 1200 |
2/2✓ Branch 0 taken 618837 times.
✓ Branch 1 taken 20329426 times.
|
20948263 | (lex->sql_command == SQLCOM_CREATE_TABLE && |
| 1201 |
4/4✓ Branch 0 taken 20948263 times.
✓ Branch 1 taken 416069 times.
✓ Branch 2 taken 47660 times.
✓ Branch 3 taken 571177 times.
|
42360255 | !(lex->create_info->options & HA_LEX_CREATE_TMP_TABLE)) || |
| 1202 |
4/4✓ Branch 0 taken 160736 times.
✓ Branch 1 taken 20216350 times.
✓ Branch 2 taken 153648 times.
✓ Branch 3 taken 7088 times.
|
41741418 | (lex->sql_command == SQLCOM_DROP_TABLE && !lex->drop_temporary); |
| 1203 | } | ||
| 1204 | |||
| 1205 | 33 | void execute_init_command(THD *thd, LEX_STRING *init_command, | |
| 1206 | mysql_rwlock_t *var_lock) { | ||
| 1207 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | Protocol_classic *protocol = thd->get_protocol_classic(); |
| 1208 | Vio *save_vio; | ||
| 1209 | ulong save_client_capabilities; | ||
| 1210 | COM_DATA com_data; | ||
| 1211 | |||
| 1212 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | mysql_rwlock_rdlock(var_lock); |
| 1213 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
|
33 | if (!init_command->length) { |
| 1214 | ✗ | mysql_rwlock_unlock(var_lock); | |
| 1215 | ✗ | return; | |
| 1216 | } | ||
| 1217 | |||
| 1218 | /* | ||
| 1219 | copy the value under a lock, and release the lock. | ||
| 1220 | init_command has to be executed without a lock held, | ||
| 1221 | as it may try to change itself | ||
| 1222 | */ | ||
| 1223 | 33 | size_t len = init_command->length; | |
| 1224 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | char *buf = thd->strmake(init_command->str, len); |
| 1225 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | mysql_rwlock_unlock(var_lock); |
| 1226 | |||
| 1227 | #if defined(ENABLED_PROFILING) | ||
| 1228 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | thd->profiling->start_new_query(); |
| 1229 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | thd->profiling->set_query_source(buf, len); |
| 1230 | #endif | ||
| 1231 | |||
| 1232 | /* | ||
| 1233 | Clear the DA in anticipation of possible failures in anticipation | ||
| 1234 | of possible command parsing failures. | ||
| 1235 | */ | ||
| 1236 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | thd->get_stmt_da()->reset_diagnostics_area(); |
| 1237 | |||
| 1238 | /* For per-query performance counters with log_slow_statement */ | ||
| 1239 | struct System_status_var query_start_status; | ||
| 1240 | 33 | thd->clear_copy_status_var(); | |
| 1241 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
|
33 | if (opt_log_slow_extra) { |
| 1242 | ✗ | thd->copy_status_var(&query_start_status); | |
| 1243 | } | ||
| 1244 | |||
| 1245 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | THD_STAGE_INFO(thd, stage_execution_of_init_command); |
| 1246 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | save_client_capabilities = protocol->get_client_capabilities(); |
| 1247 | 33 | protocol->add_client_capability(CLIENT_MULTI_QUERIES); | |
| 1248 | /* | ||
| 1249 | We do not prepare a COM_QUERY packet with query attributes | ||
| 1250 | since the init commands have nobody to supply query attributes. | ||
| 1251 | */ | ||
| 1252 | 33 | protocol->remove_client_capability(CLIENT_QUERY_ATTRIBUTES); | |
| 1253 | /* | ||
| 1254 | We don't need return result of execution to client side. | ||
| 1255 | To forbid this we should set thd->net.vio to 0. | ||
| 1256 | */ | ||
| 1257 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | save_vio = protocol->get_vio(); |
| 1258 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | protocol->set_vio(nullptr); |
| 1259 |
2/4✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
|
33 | if (!protocol->create_command(&com_data, COM_QUERY, (uchar *)buf, len)) |
| 1260 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | dispatch_command(thd, &com_data, COM_QUERY); |
| 1261 | 33 | protocol->set_client_capabilities(save_client_capabilities); | |
| 1262 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | protocol->set_vio(save_vio); |
| 1263 | |||
| 1264 | #if defined(ENABLED_PROFILING) | ||
| 1265 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | thd->profiling->finish_current_query(); |
| 1266 | #endif | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | /* This works because items are allocated with (*THR_MALLOC)->Alloc() */ | ||
| 1270 | |||
| 1271 | 98708 | void free_items(Item *item) { | |
| 1272 | Item *next; | ||
| 1273 |
1/2✓ Branch 0 taken 98708 times.
✗ Branch 1 not taken.
|
98708 | DBUG_TRACE; |
| 1274 |
2/2✓ Branch 0 taken 1006427 times.
✓ Branch 1 taken 98708 times.
|
1105135 | for (; item; item = next) { |
| 1275 | 1006427 | next = item->next_free; | |
| 1276 | 1006427 | item->delete_self(); | |
| 1277 | } | ||
| 1278 | 98708 | } | |
| 1279 | |||
| 1280 | /** | ||
| 1281 | This works because items are allocated with (*THR_MALLOC)->Alloc(). | ||
| 1282 | @note The function also handles null pointers (empty list). | ||
| 1283 | */ | ||
| 1284 | 50832566 | void cleanup_items(Item *item) { | |
| 1285 |
1/2✓ Branch 0 taken 50836030 times.
✗ Branch 1 not taken.
|
50832566 | DBUG_TRACE; |
| 1286 |
3/4✓ Branch 0 taken 499072746 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 499081170 times.
✓ Branch 3 taken 50827606 times.
|
549908776 | for (; item; item = item->next_free) item->cleanup(); |
| 1287 | 50827606 | } | |
| 1288 | |||
| 1289 | #ifdef WITH_WSREP | ||
| 1290 | 1557 | static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables) { | |
| 1291 | 1557 | bool has_tables = false; | |
| 1292 |
2/2✓ Branch 0 taken 1325 times.
✓ Branch 1 taken 1209 times.
|
2534 | for (const TABLE_LIST *table = tables; table; table = table->next_global) { |
| 1293 | TABLE_CATEGORY c; | ||
| 1294 | LEX_CSTRING db, tn; | ||
| 1295 | |||
| 1296 | /* PXC-2557 : skip if NULL, otherwise lex_string_set will crash */ | ||
| 1297 |
2/4✓ Branch 0 taken 1325 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1325 times.
|
1325 | if (!table->db || !table->table_name) continue; |
| 1298 | |||
| 1299 | 1325 | lex_cstring_set(&db, const_cast<char *>(table->db)); | |
| 1300 | 1325 | lex_cstring_set(&tn, const_cast<char *>(table->table_name)); | |
| 1301 |
1/2✓ Branch 0 taken 1325 times.
✗ Branch 1 not taken.
|
1325 | c = get_table_category(db, tn); |
| 1302 |
4/4✓ Branch 0 taken 1319 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 348 times.
✓ Branch 3 taken 971 times.
|
1325 | if (c != TABLE_CATEGORY_INFORMATION && c != TABLE_CATEGORY_PERFORMANCE) { |
| 1303 | 348 | return false; | |
| 1304 | } | ||
| 1305 | 977 | has_tables = true; | |
| 1306 | } | ||
| 1307 | 1209 | return has_tables; | |
| 1308 | } | ||
| 1309 | #endif /* WITH_WSREP */ | ||
| 1310 | |||
| 1311 | /** | ||
| 1312 | Bind Item fields to Field objects. | ||
| 1313 | |||
| 1314 | @param first Pointer to first item, follow "next" chain to visit all items | ||
| 1315 | */ | ||
| 1316 | 12697472 | void bind_fields(Item *first) { | |
| 1317 |
2/2✓ Branch 0 taken 148058964 times.
✓ Branch 1 taken 12696489 times.
|
160755453 | for (Item *item = first; item; item = item->next_free) item->bind_fields(); |
| 1318 | 12696489 | } | |
| 1319 | |||
| 1320 | /** | ||
| 1321 | Checks if the period net_buffer_shrink_interval is over. | ||
| 1322 | */ | ||
| 1323 | 11085646 | static bool net_buffer_shrink_interval_is_over( | |
| 1324 | const THD *const thd, unsigned long long net_buffer_shrink_time) { | ||
| 1325 | // N.B. Make a copy to use the same variable during all the function | ||
| 1326 | // as it could be modified in another session. | ||
| 1327 | 11085646 | auto interval = net_buffer_shrink_interval; | |
| 1328 | |||
| 1329 |
2/2✓ Branch 0 taken 486 times.
✓ Branch 1 taken 11085160 times.
|
11086132 | return interval != 0 && |
| 1330 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 477 times.
|
11086132 | thd->start_utime / 1000000 > net_buffer_shrink_time + interval; |
| 1331 | } | ||
| 1332 | |||
| 1333 | /** | ||
| 1334 | Shrinks the packet buffer if the max size during the last | ||
| 1335 | global.net_buffer_shrink_interval is smaller than the current size. | ||
| 1336 | */ | ||
| 1337 | 11084702 | static bool shrink_packet_buffer(THD *thd, unsigned long *max_interval_packet, | |
| 1338 | unsigned long long *net_buffer_shrink_time) { | ||
| 1339 |
1/2✓ Branch 0 taken 11085747 times.
✗ Branch 1 not taken.
|
11084702 | if (!net_buffer_shrink_interval_is_over(thd, *net_buffer_shrink_time)) { |
| 1340 | 11085747 | return false; | |
| 1341 | } | ||
| 1342 | |||
| 1343 | ✗ | auto net = thd->get_protocol_classic()->get_net(); | |
| 1344 | 9 | auto was_shrunk = my_net_shrink_buffer(net, thd->variables.net_buffer_length, | |
| 1345 | max_interval_packet); | ||
| 1346 | 9 | *net_buffer_shrink_time = thd->start_utime / 1000000; | |
| 1347 | 9 | return was_shrunk; | |
| 1348 | } | ||
| 1349 | |||
| 1350 | /** | ||
| 1351 | Read one command from connection and execute it (query or simple command). | ||
| 1352 | This function is called in loop from thread function. | ||
| 1353 | |||
| 1354 | For profiling to work, it must never be called recursively. | ||
| 1355 | |||
| 1356 | @retval | ||
| 1357 | 0 success | ||
| 1358 | @retval | ||
| 1359 | 1 request of thread shutdown (see dispatch_command() description) | ||
| 1360 | */ | ||
| 1361 | |||
| 1362 | 11090017 | bool do_command(THD *thd) { | |
| 1363 | bool return_value; | ||
| 1364 | int rc; | ||
| 1365 | 11090017 | NET *net = nullptr; | |
| 1366 | 11090017 | enum enum_server_command command = COM_SLEEP; | |
| 1367 | COM_DATA com_data; | ||
| 1368 |
1/2✓ Branch 0 taken 11091979 times.
✗ Branch 1 not taken.
|
11090017 | DBUG_TRACE; |
| 1369 |
2/4✓ Branch 0 taken 11091834 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11091834 times.
|
11091979 | assert(thd->is_classic_protocol()); |
| 1370 | |||
| 1371 | /* | ||
| 1372 | indicator of uninitialized lex => normal flow of errors handling | ||
| 1373 | (see my_message_sql) | ||
| 1374 | */ | ||
| 1375 |
1/2✓ Branch 0 taken 11092003 times.
✗ Branch 1 not taken.
|
11091834 | thd->lex->set_current_query_block(nullptr); |
| 1376 | |||
| 1377 | /* | ||
| 1378 | XXX: this code is here only to clear possible errors of init_connect. | ||
| 1379 | Consider moving to prepare_new_connection_state() instead. | ||
| 1380 | That requires making sure the DA is cleared before non-parsing statements | ||
| 1381 | such as COM_QUIT. | ||
| 1382 | */ | ||
| 1383 |
1/2✓ Branch 0 taken 11092302 times.
✗ Branch 1 not taken.
|
11092003 | thd->clear_error(); // Clear error message |
| 1384 |
1/2✓ Branch 0 taken 11092376 times.
✗ Branch 1 not taken.
|
11092302 | thd->get_stmt_da()->reset_diagnostics_area(); |
| 1385 | 11092376 | thd->updated_row_count = 0; | |
| 1386 | 11092376 | thd->busy_time = 0; | |
| 1387 | 11092376 | thd->cpu_time = 0; | |
| 1388 | 11092376 | thd->bytes_received = 0; | |
| 1389 | 11092376 | thd->bytes_sent = 0; | |
| 1390 | 11092376 | thd->binlog_bytes_written = 0; | |
| 1391 | |||
| 1392 | /* | ||
| 1393 | This thread will do a blocking read from the client which | ||
| 1394 | will be interrupted when the next command is received from | ||
| 1395 | the client, the connection is closed or "net_wait_timeout" | ||
| 1396 | number of seconds has passed. | ||
| 1397 | */ | ||
| 1398 |
2/4✓ Branch 0 taken 11092262 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11091490 times.
✗ Branch 3 not taken.
|
11092376 | net = thd->get_protocol_classic()->get_net(); |
| 1399 |
2/2✓ Branch 0 taken 11087359 times.
✓ Branch 1 taken 4131 times.
|
11091490 | if (!thd->skip_wait_timeout) |
| 1400 |
1/2✓ Branch 0 taken 11088226 times.
✗ Branch 1 not taken.
|
11087359 | my_net_set_read_timeout(net, thd->get_wait_timeout()); |
| 1401 | 11092357 | net_new_transaction(net); | |
| 1402 | |||
| 1403 | /* | ||
| 1404 | Synchronization point for testing of KILL_CONNECTION. | ||
| 1405 | This sync point can wait here, to simulate slow code execution | ||
| 1406 | between the last test of thd->killed and blocking in read(). | ||
| 1407 | |||
| 1408 | The goal of this test is to verify that a connection does not | ||
| 1409 | hang, if it is killed at this point of execution. | ||
| 1410 | (Bug#37780 - main.kill fails randomly) | ||
| 1411 | |||
| 1412 | Note that the sync point wait itself will be terminated by a | ||
| 1413 | kill. In this case it consumes a condition broadcast, but does | ||
| 1414 | not change anything else. The consumed broadcast should not | ||
| 1415 | matter here, because the read/recv() below doesn't use it. | ||
| 1416 | */ | ||
| 1417 |
3/4✓ Branch 0 taken 11087696 times.
✓ Branch 1 taken 4277 times.
✓ Branch 2 taken 11087870 times.
✗ Branch 3 not taken.
|
11092357 | DEBUG_SYNC(thd, "before_do_command_net_read"); |
| 1418 | |||
| 1419 | /* For per-query performance counters with log_slow_statement */ | ||
| 1420 | struct System_status_var query_start_status; | ||
| 1421 | 11092147 | thd->clear_copy_status_var(); | |
| 1422 |
2/2✓ Branch 0 taken 507 times.
✓ Branch 1 taken 11091126 times.
|
11091633 | if (opt_log_slow_extra) { |
| 1423 | 507 | thd->copy_status_var(&query_start_status); | |
| 1424 | } | ||
| 1425 | |||
| 1426 |
1/2✓ Branch 0 taken 11091610 times.
✗ Branch 1 not taken.
|
11091633 | rc = thd->m_mem_cnt.reset(); |
| 1427 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11091608 times.
|
11091610 | if (rc) |
| 1428 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
2 | thd->m_mem_cnt.set_thd_error_status(); |
| 1429 | else { | ||
| 1430 | /* | ||
| 1431 | Because of networking layer callbacks in place, | ||
| 1432 | this call will maintain the following instrumentation: | ||
| 1433 | - IDLE events | ||
| 1434 | - SOCKET events | ||
| 1435 | - STATEMENT events | ||
| 1436 | - STAGE events | ||
| 1437 | when reading a new network packet. | ||
| 1438 | In particular, a new instrumented statement is started. | ||
| 1439 | See init_net_server_extension() | ||
| 1440 | */ | ||
| 1441 | 11091608 | thd->m_server_idle = true; | |
| 1442 |
1/2✓ Branch 0 taken 11091145 times.
✗ Branch 1 not taken.
|
11091608 | rc = thd->get_protocol()->get_command(&com_data, &command); |
| 1443 | 11091145 | thd->m_server_idle = false; | |
| 1444 | } | ||
| 1445 | |||
| 1446 |
2/2✓ Branch 0 taken 3590 times.
✓ Branch 1 taken 11087564 times.
|
11091154 | if (rc) { |
| 1447 | #ifndef NDEBUG | ||
| 1448 | char desc[VIO_DESCRIPTION_SIZE]; | ||
| 1449 |
1/2✓ Branch 0 taken 3591 times.
✗ Branch 1 not taken.
|
3590 | vio_description(net->vio, desc); |
| 1450 |
3/8✓ Branch 0 taken 3591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3590 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3590 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
3591 | DBUG_PRINT("info", ("Got error %d reading command from socket %s", |
| 1451 | net->error, desc)); | ||
| 1452 | #endif // NDEBUG | ||
| 1453 | /* Instrument this broken statement as "statement/com/error" */ | ||
| 1454 |
1/2✓ Branch 0 taken 3590 times.
✗ Branch 1 not taken.
|
3590 | thd->m_statement_psi = MYSQL_REFINE_STATEMENT( |
| 1455 | thd->m_statement_psi, com_statement_info[COM_END].m_key); | ||
| 1456 | |||
| 1457 | /* Check if we can continue without closing the connection */ | ||
| 1458 | |||
| 1459 | /* The error must be set. */ | ||
| 1460 |
2/4✓ Branch 0 taken 3590 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3590 times.
|
3590 | assert(thd->is_error()); |
| 1461 |
1/2✓ Branch 0 taken 3590 times.
✗ Branch 1 not taken.
|
3590 | thd->send_statement_status(); |
| 1462 | |||
| 1463 | /* Mark the statement completed. */ | ||
| 1464 |
1/2✓ Branch 0 taken 3589 times.
✗ Branch 1 not taken.
|
3590 | MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); |
| 1465 | 3589 | thd->m_statement_psi = nullptr; | |
| 1466 | 3589 | thd->m_digest = nullptr; | |
| 1467 | |||
| 1468 |
2/2✓ Branch 0 taken 3587 times.
✓ Branch 1 taken 2 times.
|
3589 | if (rc < 0) { |
| 1469 | 3587 | return_value = true; // We have to close it. | |
| 1470 | 3587 | goto out; | |
| 1471 | } | ||
| 1472 | 2 | net->error = NET_ERROR_UNSET; | |
| 1473 | 2 | return_value = false; | |
| 1474 | 2 | goto out; | |
| 1475 | } | ||
| 1476 | |||
| 1477 | #ifndef NDEBUG | ||
| 1478 | char desc[VIO_DESCRIPTION_SIZE]; | ||
| 1479 |
1/2✓ Branch 0 taken 11087349 times.
✗ Branch 1 not taken.
|
11087564 | vio_description(net->vio, desc); |
| 1480 |
5/8✓ Branch 0 taken 11087468 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11087474 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 202 times.
✓ Branch 5 taken 11087272 times.
✓ Branch 6 taken 202 times.
✗ Branch 7 not taken.
|
11087349 | DBUG_PRINT("info", ("Command on %s = %d (%s)", desc, command, |
| 1481 | Command_names::str_notranslate(command).c_str())); | ||
| 1482 | #endif // NDEBUG | ||
| 1483 | |||
| 1484 | #ifdef WITH_WSREP | ||
| 1485 | /* | ||
| 1486 | Aborted by background rollbacker thread. | ||
| 1487 | Handle error here and jump straight to out | ||
| 1488 | */ | ||
| 1489 |
3/4✓ Branch 0 taken 11087461 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 11087397 times.
|
11087474 | if (wsrep_before_command(thd)) { |
| 1490 |
1/2✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
|
64 | thd->store_globals(); |
| 1491 |
1/2✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
|
64 | WSREP_LOG_THD(thd, "enter found BF aborted"); |
| 1492 | /* We don't expect stmt/transactional locks. Explicit locks are allowed */ | ||
| 1493 |
2/4✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
|
64 | assert(!thd->mdl_context.has_stmt_locks()); |
| 1494 |
2/4✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
|
64 | assert(!thd->mdl_context.has_transactional_locks()); |
| 1495 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
|
64 | assert(!thd->get_stmt_da()->is_set()); |
| 1496 | /* We let COM_QUIT and COM_STMT_CLOSE to execute even if wsrep aborted. */ | ||
| 1497 |
3/4✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53 times.
✓ Branch 3 taken 11 times.
|
64 | if (command != COM_STMT_CLOSE && command != COM_QUIT) { |
| 1498 |
1/2✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
|
53 | my_error(ER_LOCK_DEADLOCK, MYF(0)); |
| 1499 |
1/26✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
|
53 | WSREP_DEBUG("Deadlock error for: %s", thd->query().str); |
| 1500 | 53 | thd->killed = THD::NOT_KILLED; | |
| 1501 | 53 | thd->wsrep_retry_counter = 0; | |
| 1502 | |||
| 1503 | /* Instrument this broken statement as "statement/com/error" */ | ||
| 1504 |
1/2✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
|
53 | thd->m_statement_psi = MYSQL_REFINE_STATEMENT( |
| 1505 | thd->m_statement_psi, com_statement_info[COM_END].m_key); | ||
| 1506 | |||
| 1507 |
1/2✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
|
53 | thd->send_statement_status(); |
| 1508 | |||
| 1509 | /* Mark the statement completed. */ | ||
| 1510 |
1/2✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
|
53 | MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); |
| 1511 | 53 | thd->m_statement_psi = NULL; | |
| 1512 | 53 | thd->m_digest = NULL; | |
| 1513 | 53 | return_value = false; | |
| 1514 | |||
| 1515 |
1/2✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
|
53 | wsrep_after_command_before_result(thd); |
| 1516 | 53 | goto out; | |
| 1517 | } | ||
| 1518 | } | ||
| 1519 | |||
| 1520 |
7/8✓ Branch 0 taken 11087314 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 164973 times.
✓ Branch 3 taken 10922341 times.
✓ Branch 4 taken 164973 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 162403 times.
✓ Branch 7 taken 2570 times.
|
11087408 | if (WSREP(thd)) { |
| 1521 | /* | ||
| 1522 | * bail out if DB snapshot has not been installed. We however, | ||
| 1523 | * allow queries "SET" and "SHOW", they are trapped later in execute_command | ||
| 1524 | */ | ||
| 1525 | 487209 | if (!thd->wsrep_applier && | |
| 1526 |
7/10✓ Branch 0 taken 162403 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162403 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 161253 times.
✓ Branch 5 taken 1150 times.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 161246 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 162403 times.
|
163560 | (!wsrep_ready_get() || wsrep_reject_queries != WSREP_REJECT_NONE) && |
| 1527 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1157 times.
|
1157 | (server_command_flags[command] & CF_SKIP_WSREP_CHECK) == 0) { |
| 1528 | ✗ | my_message(ER_UNKNOWN_COM_ERROR, | |
| 1529 | "WSREP has not yet prepared node for application use", MYF(0)); | ||
| 1530 | ✗ | thd->end_statement(); | |
| 1531 | |||
| 1532 | /* Performance Schema Interface instrumentation end */ | ||
| 1533 | ✗ | MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); | |
| 1534 | ✗ | thd->m_statement_psi = NULL; | |
| 1535 | ✗ | thd->m_digest = NULL; | |
| 1536 | |||
| 1537 | ✗ | return_value = false; | |
| 1538 | ✗ | wsrep_after_command_before_result(thd); | |
| 1539 | ✗ | goto out; | |
| 1540 | } | ||
| 1541 | } | ||
| 1542 | #endif /* WITH_WSREP */ | ||
| 1543 | |||
| 1544 |
7/12✓ Branch 0 taken 11087384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11087416 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 202 times.
✓ Branch 5 taken 11087214 times.
✓ Branch 6 taken 202 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 202 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 202 times.
✗ Branch 11 not taken.
|
11087408 | DBUG_PRINT("info", ("packet: '%*.s'; command: %d", |
| 1545 | (int)thd->get_protocol_classic()->get_packet_length(), | ||
| 1546 | thd->get_protocol_classic()->get_raw_packet(), command)); | ||
| 1547 |
2/4✓ Branch 0 taken 11087332 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11087332 times.
|
11087416 | if (thd->get_protocol_classic()->bad_packet) |
| 1548 | ✗ | assert(0); // Should be caught earlier | |
| 1549 | |||
| 1550 | // Reclaim some memory | ||
| 1551 |
3/6✓ Branch 0 taken 11087425 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11087362 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11087411 times.
✗ Branch 5 not taken.
|
11087332 | thd->get_protocol_classic()->get_output_packet()->shrink( |
| 1552 | thd->variables.net_buffer_length); | ||
| 1553 | /* Restore read timeout value */ | ||
| 1554 |
1/2✓ Branch 0 taken 11087639 times.
✗ Branch 1 not taken.
|
11087411 | my_net_set_read_timeout(net, thd->variables.net_read_timeout); |
| 1555 | |||
| 1556 | 11087639 | thd->status_var.net_buffer_length = net->max_packet; | |
| 1557 | |||
| 1558 |
3/4✓ Branch 0 taken 11083624 times.
✓ Branch 1 taken 3909 times.
✓ Branch 2 taken 11083694 times.
✗ Branch 3 not taken.
|
11087639 | DEBUG_SYNC(thd, "before_command_dispatch"); |
| 1559 | |||
| 1560 |
1/2✓ Branch 0 taken 11084550 times.
✗ Branch 1 not taken.
|
11087603 | return_value = dispatch_command(thd, &com_data, command); |
| 1561 | |||
| 1562 | #ifdef MYSQL_SERVER | ||
| 1563 | { | ||
| 1564 | 11084550 | NET_SERVER *ext = static_cast<NET_SERVER *>(net->extension); | |
| 1565 |
1/2✓ Branch 0 taken 11085693 times.
✗ Branch 1 not taken.
|
11084550 | if (ext != nullptr) |
| 1566 |
1/2✓ Branch 0 taken 11085747 times.
✗ Branch 1 not taken.
|
11085693 | shrink_packet_buffer(thd, &ext->max_interval_packet, |
| 1567 | &ext->net_buffer_shrink_time); | ||
| 1568 | } | ||
| 1569 | #endif | ||
| 1570 | |||
| 1571 |
3/6✓ Branch 0 taken 11085400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11085412 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11085401 times.
✗ Branch 5 not taken.
|
11084604 | thd->get_protocol_classic()->get_output_packet()->shrink( |
| 1572 | thd->variables.net_buffer_length); | ||
| 1573 | |||
| 1574 | 11089043 | out: | |
| 1575 | /* The statement instrumentation must be closed in all cases. */ | ||
| 1576 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11089043 times.
|
11089043 | assert(thd->m_digest == nullptr); |
| 1577 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11089043 times.
|
11089043 | assert(thd->m_statement_psi == nullptr); |
| 1578 | #ifdef WITH_WSREP | ||
| 1579 | // TODO: Need to findout significance of bad packet and execution of API | ||
| 1580 |
3/4✓ Branch 0 taken 11088310 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11085426 times.
✓ Branch 3 taken 2884 times.
|
11089043 | if (!thd->get_protocol_classic()->bad_packet) { |
| 1581 | /* there was a command to process, and before_command() has been called */ | ||
| 1582 |
1/2✓ Branch 0 taken 11085350 times.
✗ Branch 1 not taken.
|
11085426 | wsrep_after_command_after_result(thd); |
| 1583 | } | ||
| 1584 | #endif /* WITH_WSREP */ | ||
| 1585 | 11089715 | return return_value; | |
| 1586 | 11088234 | } | |
| 1587 | |||
| 1588 | /** | ||
| 1589 | @brief Determine if an attempt to update a non-temporary table while the | ||
| 1590 | read-only option was enabled has been made. | ||
| 1591 | |||
| 1592 | This is a helper function to mysql_execute_command. | ||
| 1593 | |||
| 1594 | @note SQLCOM_UPDATE_MULTI is an exception and delt with elsewhere. | ||
| 1595 | |||
| 1596 | @see mysql_execute_command | ||
| 1597 | @returns Status code | ||
| 1598 | @retval true The statement should be denied. | ||
| 1599 | @retval false The statement isn't updating any relevant tables. | ||
| 1600 | */ | ||
| 1601 | 21005693 | static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables) { | |
| 1602 |
1/2✓ Branch 0 taken 21006377 times.
✗ Branch 1 not taken.
|
21005693 | DBUG_TRACE; |
| 1603 | |||
| 1604 |
3/4✓ Branch 0 taken 21005856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20713169 times.
✓ Branch 3 taken 292687 times.
|
21006377 | if (!check_readonly(thd, false)) return false; |
| 1605 | |||
| 1606 | 292687 | LEX *lex = thd->lex; | |
| 1607 |
2/2✓ Branch 0 taken 292529 times.
✓ Branch 1 taken 158 times.
|
292687 | if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA)) return false; |
| 1608 | |||
| 1609 | /* Multi update is an exception and is dealt with later. */ | ||
| 1610 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 152 times.
|
158 | if (lex->sql_command == SQLCOM_UPDATE_MULTI) return false; |
| 1611 | |||
| 1612 | 152 | const bool create_temp_tables = | |
| 1613 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 118 times.
|
186 | (lex->sql_command == SQLCOM_CREATE_TABLE) && |
| 1614 |
2/2✓ Branch 0 taken 19 times.
✓ Branch 1 taken 15 times.
|
34 | (lex->create_info->options & HA_LEX_CREATE_TMP_TABLE); |
| 1615 | |||
| 1616 | 152 | const bool create_real_tables = | |
| 1617 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 118 times.
|
186 | (lex->sql_command == SQLCOM_CREATE_TABLE) && |
| 1618 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 19 times.
|
34 | !(lex->create_info->options & HA_LEX_CREATE_TMP_TABLE); |
| 1619 | |||
| 1620 | 152 | const bool drop_temp_tables = | |
| 1621 |
3/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
|
152 | (lex->sql_command == SQLCOM_DROP_TABLE) && lex->drop_temporary; |
| 1622 | |||
| 1623 | /* RENAME TABLES ignores shadowing temporary tables. */ | ||
| 1624 | 152 | const bool rename_tables = (lex->sql_command == SQLCOM_RENAME_TABLE); | |
| 1625 | |||
| 1626 | const bool update_real_tables = | ||
| 1627 |
2/2✓ Branch 0 taken 162 times.
✓ Branch 1 taken 1 times.
|
163 | ((create_real_tables || rename_tables || |
| 1628 |
4/6✓ Branch 0 taken 163 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 88 times.
|
378 | some_non_temp_table_to_be_updated(thd, all_tables)) && |
| 1629 |
2/4✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
|
64 | !(create_temp_tables || drop_temp_tables)); |
| 1630 | |||
| 1631 | 152 | const bool create_or_drop_databases = | |
| 1632 |
1/2✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
|
329 | (lex->sql_command == SQLCOM_CREATE_DB) || |
| 1633 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 176 times.
|
177 | (lex->sql_command == SQLCOM_DROP_DB); |
| 1634 | |||
| 1635 | 152 | const bool create_or_drop_compression_dictionary = | |
| 1636 |
1/2✓ Branch 0 taken 178 times.
✗ Branch 1 not taken.
|
330 | (lex->sql_command == SQLCOM_CREATE_COMPRESSION_DICTIONARY) || |
| 1637 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 178 times.
|
178 | (lex->sql_command == SQLCOM_DROP_COMPRESSION_DICTIONARY); |
| 1638 | |||
| 1639 |
5/6✓ Branch 0 taken 107 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 105 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 105 times.
|
152 | if (update_real_tables || create_or_drop_databases || |
| 1640 | create_or_drop_compression_dictionary) { | ||
| 1641 | /* | ||
| 1642 | An attempt was made to modify one or more non-temporary tables. | ||
| 1643 | */ | ||
| 1644 | 47 | return true; | |
| 1645 | } | ||
| 1646 | |||
| 1647 | /* Assuming that only temporary tables are modified. */ | ||
| 1648 | 105 | return false; | |
| 1649 | 21005856 | } | |
| 1650 | |||
| 1651 | #ifdef WITH_WSREP | ||
| 1652 | 151735 | static bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables) { | |
| 1653 | 151735 | int opt_readonly_saved = opt_readonly; | |
| 1654 | |||
| 1655 | 151735 | ulong master_access = thd->security_context()->master_access(); | |
| 1656 | 151736 | ulong flag_saved = (ulong)(master_access & SUPER_ACL); | |
| 1657 | |||
| 1658 | 151736 | opt_readonly = 0; | |
| 1659 | 151736 | thd->security_context()->set_master_access(master_access & ~SUPER_ACL); | |
| 1660 | |||
| 1661 | 151736 | bool ret = !deny_updates_if_read_only_option(thd, all_tables); | |
| 1662 | |||
| 1663 | 151736 | opt_readonly = opt_readonly_saved; | |
| 1664 | 151736 | thd->security_context()->set_master_access(master_access | flag_saved); | |
| 1665 | |||
| 1666 | 151737 | return ret; | |
| 1667 | } | ||
| 1668 | |||
| 1669 | 165 | static void wsrep_copy_query(THD *thd) { | |
| 1670 | 165 | thd->wsrep_retry_command = thd->get_command(); | |
| 1671 | 165 | thd->wsrep_retry_query_len = thd->query().length; | |
| 1672 |
2/2✓ Branch 0 taken 116 times.
✓ Branch 1 taken 49 times.
|
165 | if (thd->wsrep_retry_query) { |
| 1673 | 116 | my_free(thd->wsrep_retry_query); | |
| 1674 | } | ||
| 1675 | 330 | thd->wsrep_retry_query = (char *)my_malloc( | |
| 1676 | 165 | key_memory_wsrep, thd->wsrep_retry_query_len + 1, MYF(0)); | |
| 1677 | 165 | strncpy(thd->wsrep_retry_query, thd->query().str, thd->wsrep_retry_query_len); | |
| 1678 | 165 | thd->wsrep_retry_query[thd->wsrep_retry_query_len] = '\0'; | |
| 1679 | 165 | } | |
| 1680 | |||
| 1681 | /* Function should be called if any non-supported lock/unlock statement | ||
| 1682 | is executed and if the outcome has to be evaluated based on pxc-strict-mode */ | ||
| 1683 | 3281 | static bool pxc_strict_mode_lock_check(THD *thd) { | |
| 1684 | /* LOCK/UNLOCK TABLE is not supported by galera due as it not compatible | ||
| 1685 | with multi-master semantics. */ | ||
| 1686 | 3281 | bool block = false; | |
| 1687 | |||
| 1688 |
3/3✓ Branch 0 taken 3273 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
|
3281 | switch (pxc_strict_mode) { |
| 1689 | 3273 | case PXC_STRICT_MODE_DISABLED: | |
| 1690 | case PXC_STRICT_MODE_MASTER: | ||
| 1691 | /* Do nothing */ | ||
| 1692 | 3273 | break; | |
| 1693 | 4 | case PXC_STRICT_MODE_PERMISSIVE: | |
| 1694 |
10/22✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
|
4 | WSREP_WARN( |
| 1695 | "Percona-XtraDB-Cluster doesn't recommend use of" | ||
| 1696 | " LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK/FOR EXPORT" | ||
| 1697 | " with pxc_strict_mode = PERMISSIVE"); | ||
| 1698 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | push_warning_printf(thd, Sql_condition::SL_WARNING, ER_UNKNOWN_ERROR, |
| 1699 | "Percona-XtraDB-Cluster doesn't recommend use of" | ||
| 1700 | " LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK" | ||
| 1701 | " with pxc_strict_mode = PERMISSIVE"); | ||
| 1702 | 4 | break; | |
| 1703 | 4 | case PXC_STRICT_MODE_ENFORCING: | |
| 1704 | default: | ||
| 1705 | 4 | block = true; | |
| 1706 |
13/28✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
4 | WSREP_ERROR( |
| 1707 | "Percona-XtraDB-Cluster prohibits use of" | ||
| 1708 | " LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK/FOR EXPORT" | ||
| 1709 | " with pxc_strict_mode = ENFORCING"); | ||
| 1710 | char message[1024]; | ||
| 1711 | 4 | sprintf(message, | |
| 1712 | "Percona-XtraDB-Cluster prohibits use of" | ||
| 1713 | " LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK/FOR EXPORT" | ||
| 1714 | " with pxc_strict_mode = ENFORCING"); | ||
| 1715 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | my_message(ER_UNKNOWN_ERROR, message, MYF(0)); |
| 1716 | 4 | break; | |
| 1717 | } | ||
| 1718 | |||
| 1719 | 3281 | return block; | |
| 1720 | } | ||
| 1721 | /* | ||
| 1722 | * This function should be called to determine if cluster still has nodes | ||
| 1723 | * with lower versions of wsrep_protocol_version (eg.: version 3). | ||
| 1724 | * Writing on a new node can crash nodes with lower version 8.0->5.7 | ||
| 1725 | */ | ||
| 1726 | 279402 | static bool block_write_while_in_rolling_upgrade(THD *thd) { | |
| 1727 | /* Ignore check while server is not ready or for background wsrep applier too | ||
| 1728 | * (like slave thread) */ | ||
| 1729 |
10/14✓ Branch 0 taken 268660 times.
✓ Branch 1 taken 10887 times.
✓ Branch 2 taken 268661 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 268661 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 268661 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 268661 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 32222 times.
✓ Branch 11 taken 236439 times.
✓ Branch 12 taken 43105 times.
✓ Branch 13 taken 236442 times.
|
279402 | if (!wsrep_node_is_synced() || (WSREP(thd) && thd->wsrep_applier)) |
| 1730 | 43105 | return false; | |
| 1731 | |||
| 1732 | 236442 | bool block = false; | |
| 1733 | 236442 | LEX *lex = thd->lex; | |
| 1734 |
2/2✓ Branch 0 taken 44994 times.
✓ Branch 1 taken 191448 times.
|
236442 | if (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) { |
| 1735 | 44994 | bool multi_version_cluster = wsrep_protocol_version < 4; | |
| 1736 |
3/4✓ Branch 0 taken 44994 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 44987 times.
|
89987 | if (multi_version_cluster || |
| 1737 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 44987 times.
|
44994 | DBUG_EVALUATE_IF("simulate_wsrep_multiple_major_versions", true, |
| 1738 | false)) { | ||
| 1739 | const char *msg; | ||
| 1740 |
2/3✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
|
6 | switch (pxc_strict_mode) { |
| 1741 | ✗ | case PXC_STRICT_MODE_DISABLED: | |
| 1742 | /* Do nothing */ | ||
| 1743 | ✗ | break; | |
| 1744 | 3 | case PXC_STRICT_MODE_PERMISSIVE: | |
| 1745 | 3 | msg = | |
| 1746 | "Percona-XtraDB-Cluster doesn't recommend use of multiple major" | ||
| 1747 | " versions while accepting write workload" | ||
| 1748 | " with pxc_strict_mode = PERMISSIVE"; | ||
| 1749 |
9/18✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
|
3 | WSREP_WARN("%s", msg); |
| 1750 | 3 | push_warning_printf(thd, Sql_condition::SL_WARNING, ER_UNKNOWN_ERROR, | |
| 1751 | "%s", msg); | ||
| 1752 | 3 | break; | |
| 1753 | 3 | case PXC_STRICT_MODE_MASTER: | |
| 1754 | case PXC_STRICT_MODE_ENFORCING: | ||
| 1755 | default: | ||
| 1756 | 3 | block = true; | |
| 1757 | 3 | msg = | |
| 1758 | "Percona-XtraDB-Cluster prohibits use of multiple major versions" | ||
| 1759 | " while accepting write workload with pxc_strict_mode = " | ||
| 1760 | "ENFORCING or MASTER"; | ||
| 1761 |
12/24✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 3 times.
|
3 | WSREP_ERROR("%s", msg); |
| 1762 | 3 | my_message(ER_UNKNOWN_ERROR, msg, MYF(0)); | |
| 1763 | 3 | break; | |
| 1764 | } | ||
| 1765 | } | ||
| 1766 | } | ||
| 1767 | 236441 | return block; | |
| 1768 | } | ||
| 1769 | #endif /* WITH_WSREP */ | ||
| 1770 | |||
| 1771 | /** | ||
| 1772 | Check if a statement should be restarted in another storage engine, | ||
| 1773 | and restart the statement if needed. | ||
| 1774 | |||
| 1775 | @param thd the session | ||
| 1776 | @param parser_state the parser state | ||
| 1777 | @param query_string the query to reprepare and execute | ||
| 1778 | @param query_length the length of the query | ||
| 1779 | */ | ||
| 1780 | 11101970 | static void check_secondary_engine_statement(THD *thd, | |
| 1781 | Parser_state *parser_state, | ||
| 1782 | const char *query_string, | ||
| 1783 | size_t query_length) { | ||
| 1784 | #ifdef WITH_WSREP | ||
| 1785 |
6/8✓ Branch 0 taken 11102050 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162900 times.
✓ Branch 3 taken 10939150 times.
✓ Branch 4 taken 162901 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 157756 times.
✓ Branch 7 taken 5145 times.
|
11101970 | if (WSREP(thd)) { |
| 1786 | /* While running in cluster mode disable the check for now */ | ||
| 1787 | 157756 | return; | |
| 1788 | } | ||
| 1789 | #endif /* WITH_WSREP */ | ||
| 1790 | |||
| 1791 | 10944214 | bool use_secondary_engine = false; | |
| 1792 | |||
| 1793 | // Only restart the statement if a non-fatal error was raised. | ||
| 1794 |
8/8✓ Branch 0 taken 77235 times.
✓ Branch 1 taken 10867391 times.
✓ Branch 2 taken 76970 times.
✓ Branch 3 taken 265 times.
✓ Branch 4 taken 438 times.
✓ Branch 5 taken 76566 times.
✓ Branch 6 taken 10868180 times.
✓ Branch 7 taken 76480 times.
|
10944214 | if (!thd->is_error() || thd->is_killed() || thd->is_fatal_error()) return; |
| 1795 | |||
| 1796 | // Only SQL commands can be restarted with another storage engine. | ||
| 1797 |
2/2✓ Branch 0 taken 36800 times.
✓ Branch 1 taken 39680 times.
|
76480 | if (thd->lex->m_sql_cmd == nullptr) return; |
| 1798 | |||
| 1799 | // The query cannot be restarted if it had started executing, since | ||
| 1800 | // it may have started sending results to the client. | ||
| 1801 |
2/2✓ Branch 0 taken 7941 times.
✓ Branch 1 taken 31825 times.
|
39680 | if (thd->lex->is_exec_completed()) return; |
| 1802 | |||
| 1803 | // Decide which storage engine to use when retrying. | ||
| 1804 |
3/3✓ Branch 0 taken 31669 times.
✓ Branch 1 taken 131 times.
✓ Branch 2 taken 25 times.
|
31825 | switch (thd->secondary_engine_optimization()) { |
| 1805 | 31669 | case Secondary_engine_optimization::PRIMARY_TENTATIVELY: | |
| 1806 | // If a request to prepare for the secondary engine was | ||
| 1807 | // signalled, retry in the secondary engine. | ||
| 1808 |
2/2✓ Branch 0 taken 31436 times.
✓ Branch 1 taken 233 times.
|
31669 | if (thd->get_stmt_da()->mysql_errno() != ER_PREPARE_FOR_SECONDARY_ENGINE) |
| 1809 | 31436 | return; | |
| 1810 | 233 | thd->set_secondary_engine_optimization( | |
| 1811 | Secondary_engine_optimization::SECONDARY); | ||
| 1812 | 233 | use_secondary_engine = true; | |
| 1813 | 233 | break; | |
| 1814 | 131 | case Secondary_engine_optimization::SECONDARY: | |
| 1815 | // If the query failed during offloading to a secondary engine, | ||
| 1816 | // retry in the primary engine. Don't retry if the failing query | ||
| 1817 | // was already using the primary storage engine. | ||
| 1818 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 124 times.
|
131 | if (!thd->lex->m_sql_cmd->using_secondary_storage_engine()) return; |
| 1819 | 124 | thd->set_secondary_engine_optimization( | |
| 1820 | Secondary_engine_optimization::PRIMARY_ONLY); | ||
| 1821 | 124 | break; | |
| 1822 | 25 | default: | |
| 1823 | 25 | return; | |
| 1824 | } | ||
| 1825 | |||
| 1826 | // Forget about the error raised in the previous attempt at preparing the | ||
| 1827 | // query. | ||
| 1828 | 357 | thd->clear_error(); | |
| 1829 | |||
| 1830 | // Tell performance schema that the statement is restarted. | ||
| 1831 | 357 | MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); | |
| 1832 | |||
| 1833 | 357 | mysql_thread_set_secondary_engine(use_secondary_engine); | |
| 1834 | |||
| 1835 | 357 | thd->m_statement_psi = MYSQL_START_STATEMENT( | |
| 1836 | &thd->m_statement_state, com_statement_info[thd->get_command()].m_key, | ||
| 1837 | thd->db().str, thd->db().length, thd->charset(), nullptr); | ||
| 1838 | |||
| 1839 | 357 | mysql_statement_set_secondary_engine(thd->m_statement_psi, | |
| 1840 | use_secondary_engine); | ||
| 1841 | |||
| 1842 |
1/2✓ Branch 0 taken 357 times.
✗ Branch 1 not taken.
|
357 | DEBUG_SYNC(thd, "retry_secondary_engine"); |
| 1843 | |||
| 1844 | // Reset the statement digest state. | ||
| 1845 | 357 | thd->m_digest = &thd->m_digest_state; | |
| 1846 | 357 | thd->m_digest->reset(thd->m_token_array, max_digest_length); | |
| 1847 | |||
| 1848 | // Reset the parser state. | ||
| 1849 | 357 | thd->set_query(query_string, query_length); | |
| 1850 | 357 | parser_state->reset(query_string, query_length); | |
| 1851 | |||
| 1852 | // Disable the general log. The query was written to the general log in the | ||
| 1853 | // first attempt to execute it. No need to write it twice. | ||
| 1854 | 357 | const uint64_t saved_option_bits = thd->variables.option_bits; | |
| 1855 | 357 | thd->variables.option_bits |= OPTION_LOG_OFF; | |
| 1856 | |||
| 1857 | // Restart the statement. | ||
| 1858 | 357 | dispatch_sql_command(thd, parser_state, true); | |
| 1859 | |||
| 1860 | // Restore the original option bits. | ||
| 1861 | 357 | thd->variables.option_bits = saved_option_bits; | |
| 1862 | |||
| 1863 | // Check if the restarted statement failed, and if so, if it needs | ||
| 1864 | // another restart/fallback to the primary storage engine. | ||
| 1865 | 357 | check_secondary_engine_statement(thd, parser_state, query_string, | |
| 1866 | query_length); | ||
| 1867 | } | ||
| 1868 | |||
| 1869 | /*Reference to the GR callback that receives incoming connections*/ | ||
| 1870 | static std::atomic<gr_incoming_connection_cb> com_incoming_gr_stream_cb; | ||
| 1871 | |||
| 1872 | 2484 | void set_gr_incoming_connection(gr_incoming_connection_cb x) { | |
| 1873 | 2484 | com_incoming_gr_stream_cb.store(x); | |
| 1874 | 2484 | } | |
| 1875 | |||
| 1876 | 810 | gr_incoming_connection_cb get_gr_incoming_connection() { | |
| 1877 | 810 | gr_incoming_connection_cb retval = nullptr; | |
| 1878 | 810 | retval = com_incoming_gr_stream_cb.load(); | |
| 1879 | 810 | return retval; | |
| 1880 | } | ||
| 1881 | |||
| 1882 | 368 | void call_gr_incoming_connection_cb(THD *thd, int fd, SSL *ssl_ctx) { | |
| 1883 | gr_incoming_connection_cb gr_connection_callback = | ||
| 1884 | 368 | get_gr_incoming_connection(); | |
| 1885 | |||
| 1886 |
1/2✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
|
368 | if (gr_connection_callback) { |
| 1887 |
1/2✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
|
368 | gr_connection_callback(thd, fd, ssl_ctx); |
| 1888 | |||
| 1889 | 368 | PSI_stage_info saved_stage; | |
| 1890 |
1/2✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
|
368 | mysql_mutex_lock(&thd->LOCK_group_replication_connection_mutex); |
| 1891 |
1/2✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
|
368 | thd->ENTER_COND(&thd->COND_group_replication_connection_cond_var, |
| 1892 | &thd->LOCK_group_replication_connection_mutex, | ||
| 1893 | &stage_communication_delegation, &saved_stage); | ||
| 1894 |
2/2✓ Branch 0 taken 1701 times.
✓ Branch 1 taken 367 times.
|
2068 | while (thd->is_killed() == THD::NOT_KILLED) { |
| 1895 | struct timespec abstime; | ||
| 1896 |
1/2✓ Branch 0 taken 1701 times.
✗ Branch 1 not taken.
|
1701 | set_timespec(&abstime, 1); |
| 1897 |
1/2✓ Branch 0 taken 1700 times.
✗ Branch 1 not taken.
|
1701 | mysql_cond_timedwait(&thd->COND_group_replication_connection_cond_var, |
| 1898 | &thd->LOCK_group_replication_connection_mutex, | ||
| 1899 | &abstime); | ||
| 1900 | } | ||
| 1901 |
1/2✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
|
367 | mysql_mutex_unlock(&thd->LOCK_group_replication_connection_mutex); |
| 1902 |
1/2✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
|
368 | thd->EXIT_COND(&saved_stage); |
| 1903 | } | ||
| 1904 | 368 | } | |
| 1905 | |||
| 1906 | /** | ||
| 1907 | Deep copy the name and value of named parameters into the THD memory. | ||
| 1908 | |||
| 1909 | We need to do this since the packet bytes will go away during query | ||
| 1910 | processing. | ||
| 1911 | It doesn't need to be done for the unnamed ones since they're being | ||
| 1912 | copied by and into Item_param. So we don't want to duplicate this. | ||
| 1913 | @sa @ref Item_param | ||
| 1914 | |||
| 1915 | @param thd the thread to copy the parameters to. | ||
| 1916 | @param parameters the values to copy | ||
| 1917 | @param count the number of parameters to copy | ||
| 1918 | */ | ||
| 1919 | 11027774 | static void copy_bind_parameter_values(THD *thd, PS_PARAM *parameters, | |
| 1920 | unsigned long count) { | ||
| 1921 | 11027774 | thd->bind_parameter_values = parameters; | |
| 1922 | 11027774 | thd->bind_parameter_values_count = count; | |
| 1923 | unsigned long inx; | ||
| 1924 | PS_PARAM *par; | ||
| 1925 |
2/2✓ Branch 0 taken 135249 times.
✓ Branch 1 taken 11027774 times.
|
11163023 | for (inx = 0, par = thd->bind_parameter_values; inx < count; inx++, par++) { |
| 1926 |
3/4✓ Branch 0 taken 39 times.
✓ Branch 1 taken 135210 times.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
|
135249 | if (par->name_length && par->name) { |
| 1927 | 39 | void *newd = thd->alloc(par->name_length); | |
| 1928 | 39 | memcpy(newd, par->name, par->name_length); | |
| 1929 | 39 | par->name = reinterpret_cast<unsigned char *>(newd); | |
| 1930 | } | ||
| 1931 |
3/4✓ Branch 0 taken 135136 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 135136 times.
✗ Branch 3 not taken.
|
135249 | if (par->length && par->value) { |
| 1932 | 135136 | void *newd = thd->alloc(par->length); | |
| 1933 | 135136 | memcpy(newd, par->value, par->length); | |
| 1934 | 135136 | par->value = reinterpret_cast<unsigned char *>(newd); | |
| 1935 | } | ||
| 1936 | } | ||
| 1937 | 11027774 | } | |
| 1938 | |||
| 1939 | /** | ||
| 1940 | Perform one connection-level (COM_XXXX) command. | ||
| 1941 | |||
| 1942 | @param thd connection handle | ||
| 1943 | @param command type of command to perform | ||
| 1944 | @param com_data com_data union to store the generated command | ||
| 1945 | |||
| 1946 | @todo | ||
| 1947 | set thd->lex->sql_command to SQLCOM_END here. | ||
| 1948 | @todo | ||
| 1949 | The following has to be changed to an 8 byte integer | ||
| 1950 | |||
| 1951 | @retval | ||
| 1952 | 0 ok | ||
| 1953 | @retval | ||
| 1954 | 1 request of thread shutdown, i. e. if command is | ||
| 1955 | COM_QUIT | ||
| 1956 | */ | ||
| 1957 | 11178499 | bool dispatch_command(THD *thd, const COM_DATA *com_data, | |
| 1958 | enum enum_server_command command) { | ||
| 1959 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11178591 times.
|
11178499 | assert(thd->lex->m_IS_table_stats.is_valid() == false); |
| 1960 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11178586 times.
|
11178591 | assert(thd->lex->m_IS_tablespace_stats.is_valid() == false); |
| 1961 | #ifndef NDEBUG | ||
| 1962 | 11176068 | auto tabstat_grd = create_scope_guard([&]() { | |
| 1963 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11176303 times.
|
11176068 | assert(thd->lex->m_IS_table_stats.is_valid() == false); |
| 1964 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11176504 times.
|
11176303 | assert(thd->lex->m_IS_tablespace_stats.is_valid() == false); |
| 1965 |
1/2✓ Branch 0 taken 11178488 times.
✗ Branch 1 not taken.
|
11178586 | }); |
| 1966 | #endif /* NDEBUG */ | ||
| 1967 | 11178488 | bool error = false; | |
| 1968 | 11178488 | Global_THD_manager *thd_manager = Global_THD_manager::get_instance(); | |
| 1969 |
1/2✓ Branch 0 taken 11178635 times.
✗ Branch 1 not taken.
|
11178406 | DBUG_TRACE; |
| 1970 |
5/8✓ Branch 0 taken 11178604 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11178502 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 202 times.
✓ Branch 5 taken 11178300 times.
✓ Branch 6 taken 202 times.
✗ Branch 7 not taken.
|
11178635 | DBUG_PRINT("info", ("command: %d", command)); |
| 1971 | |||
| 1972 |
2/14✓ Branch 0 taken 11178456 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11178456 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
11178502 | DBUG_EXECUTE_IF("crash_dispatch_command_before", { |
| 1973 | DBUG_PRINT("crash_dispatch_command_before", ("now")); | ||
| 1974 | DBUG_ABORT(); | ||
| 1975 | }); | ||
| 1976 | |||
| 1977 | 11178456 | Sql_cmd_clone *clone_cmd = nullptr; | |
| 1978 | |||
| 1979 | /* SHOW PROFILE instrumentation, begin */ | ||
| 1980 | #if defined(ENABLED_PROFILING) | ||
| 1981 |
1/2✓ Branch 0 taken 11178648 times.
✗ Branch 1 not taken.
|
11178456 | thd->profiling->start_new_query(); |
| 1982 | #endif | ||
| 1983 | |||
| 1984 | /* Performance Schema Interface instrumentation, begin */ | ||
| 1985 |
1/2✓ Branch 0 taken 11178531 times.
✗ Branch 1 not taken.
|
11178648 | thd->m_statement_psi = MYSQL_REFINE_STATEMENT( |
| 1986 | thd->m_statement_psi, com_statement_info[command].m_key); | ||
| 1987 | |||
| 1988 |
1/2✓ Branch 0 taken 11178430 times.
✗ Branch 1 not taken.
|
11178531 | thd->set_command(command); |
| 1989 | /* | ||
| 1990 | Commands which always take a long time are logged into | ||
| 1991 | the slow log only if opt_log_slow_admin_statements is set. | ||
| 1992 | */ | ||
| 1993 | 11178430 | thd->enable_slow_log = true; | |
| 1994 | // Both this and the call THD::reset_for_next_command are required, even if | ||
| 1995 | // clear_slow_extended ends up being called twice in common execution path | ||
| 1996 | // between successive commands, because some COM_* skip one or another, i.e. | ||
| 1997 | // COM_QUIT needs this one. | ||
| 1998 | 11178430 | thd->clear_slow_extended(); | |
| 1999 | 11178635 | thd->lex->sql_command = SQLCOM_END; /* to avoid confusing VIEW detectors */ | |
| 2000 | /* | ||
| 2001 | KILL QUERY may come after cleanup in mysql_execute_command(). Next query | ||
| 2002 | execution is interrupted due to this. So resetting THD::killed here. | ||
| 2003 | |||
| 2004 | THD::killed value can not be KILL_TIMEOUT here as timer used for statement | ||
| 2005 | max execution time is disarmed in the cleanup stage of | ||
| 2006 | mysql_execute_command. KILL CONNECTION should terminate the connection. | ||
| 2007 | Hence resetting THD::killed only for KILL QUERY case here. | ||
| 2008 | */ | ||
| 2009 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11178520 times.
|
11178635 | if (thd->killed == THD::KILL_QUERY) thd->killed = THD::NOT_KILLED; |
| 2010 |
1/2✓ Branch 0 taken 11178492 times.
✗ Branch 1 not taken.
|
11178521 | thd->set_time(); |
| 2011 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11178226 times.
|
11178492 | if (is_time_t_valid_for_timestamp(thd->query_start_in_secs()) == false) { |
| 2012 | /* | ||
| 2013 | If the time has gone past end of epoch we need to shutdown the server. But | ||
| 2014 | there is possibility of getting invalid time value on some platforms. | ||
| 2015 | For example, gettimeofday() might return incorrect value on solaris | ||
| 2016 | platform. Hence validating the current time with 5 iterations before | ||
| 2017 | initiating the normal server shutdown process because of time getting | ||
| 2018 | past 2038. | ||
| 2019 | */ | ||
| 2020 | ✗ | const int max_tries = 5; | |
| 2021 | ✗ | LogErr(WARNING_LEVEL, ER_CONFIRMING_THE_FUTURE, max_tries); | |
| 2022 | |||
| 2023 | ✗ | int tries = 0; | |
| 2024 | ✗ | while (++tries <= max_tries) { | |
| 2025 | ✗ | thd->set_time(); | |
| 2026 | ✗ | if (is_time_t_valid_for_timestamp(thd->query_start_in_secs()) == true) { | |
| 2027 | ✗ | LogErr(WARNING_LEVEL, ER_BACK_IN_TIME, tries); | |
| 2028 | ✗ | break; | |
| 2029 | } | ||
| 2030 | ✗ | LogErr(WARNING_LEVEL, ER_FUTURE_DATE, tries); | |
| 2031 | } | ||
| 2032 | ✗ | if (tries > max_tries) { | |
| 2033 | /* | ||
| 2034 | If the time has got past epoch, we need to shut this server down. | ||
| 2035 | We do this by making sure every command is a shutdown and we | ||
| 2036 | have enough privileges to shut the server down | ||
| 2037 | |||
| 2038 | TODO: remove this when we have full 64 bit my_time_t support | ||
| 2039 | */ | ||
| 2040 | ✗ | LogErr(ERROR_LEVEL, ER_UNSUPPORTED_DATE); | |
| 2041 | ✗ | ulong master_access = thd->security_context()->master_access(); | |
| 2042 | ✗ | thd->security_context()->set_master_access(master_access | SHUTDOWN_ACL); | |
| 2043 | ✗ | error = true; | |
| 2044 | ✗ | kill_mysql(); | |
| 2045 | } | ||
| 2046 | } | ||
| 2047 |
1/2✓ Branch 0 taken 11178600 times.
✗ Branch 1 not taken.
|
11178226 | thd->set_query_id(next_query_id()); |
| 2048 |
1/2✓ Branch 0 taken 11178543 times.
✗ Branch 1 not taken.
|
11178600 | thd->reset_rewritten_query(); |
| 2049 | 11178543 | thd_manager->inc_thread_running(); | |
| 2050 | |||
| 2051 | #ifdef WITH_WSREP | ||
| 2052 |
8/12✓ Branch 0 taken 11178681 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 167565 times.
✓ Branch 3 taken 11011116 times.
✓ Branch 4 taken 167565 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 162429 times.
✓ Branch 7 taken 5136 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 162429 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 11178652 times.
|
11178652 | if (WSREP(thd) && thd->wsrep_next_trx_id() == WSREP_UNDEFINED_TRX_ID) { |
| 2053 | ✗ | thd->set_wsrep_next_trx_id(thd->query_id); | |
| 2054 | ✗ | WSREP_DEBUG("assigned new next trx id: %" PRIu64, thd->wsrep_next_trx_id()); | |
| 2055 | } | ||
| 2056 | |||
| 2057 | 11178652 | bool do_end_of_statement = true; | |
| 2058 | #endif /* WITH_WSREP */ | ||
| 2059 | |||
| 2060 |
2/2✓ Branch 0 taken 11169097 times.
✓ Branch 1 taken 9555 times.
|
11178652 | if (!(server_command_flags[command] & CF_SKIP_QUESTIONS)) |
| 2061 | 11169097 | thd->status_var.questions++; | |
| 2062 | |||
| 2063 | /* Declare userstat variables and start timer */ | ||
| 2064 | 11178652 | double start_busy_usecs = 0.0; | |
| 2065 | 11178652 | double start_cpu_nsecs = 0.0; | |
| 2066 |
2/2✓ Branch 0 taken 1691 times.
✓ Branch 1 taken 11176786 times.
|
11178652 | if (unlikely(opt_userstat)) |
| 2067 | 1691 | userstat_start_timer(&start_busy_usecs, &start_cpu_nsecs); | |
| 2068 | |||
| 2069 | /** | ||
| 2070 | Clear the set of flags that are expected to be cleared at the | ||
| 2071 | beginning of each command. | ||
| 2072 | */ | ||
| 2073 | 11178477 | thd->server_status &= ~SERVER_STATUS_CLEAR_SET; | |
| 2074 | |||
| 2075 |
4/6✓ Branch 0 taken 11178498 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 90986 times.
✓ Branch 3 taken 11087512 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 11178498 times.
|
11269463 | if (thd->get_protocol()->type() == Protocol::PROTOCOL_PLUGIN && |
| 2076 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 90986 times.
|
90986 | !(server_command_flags[command] & CF_ALLOW_PROTOCOL_PLUGIN)) { |
| 2077 | ✗ | my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0)); | |
| 2078 | ✗ | thd->killed = THD::KILL_CONNECTION; | |
| 2079 | ✗ | error = true; | |
| 2080 | ✗ | goto done; | |
| 2081 | } | ||
| 2082 | |||
| 2083 | /** | ||
| 2084 | Enforce password expiration for all RPC commands, except the | ||
| 2085 | following: | ||
| 2086 | |||
| 2087 | COM_QUERY/COM_STMT_PREPARE and COM_STMT_EXECUTE do a more | ||
| 2088 | fine-grained check later. | ||
| 2089 | COM_STMT_CLOSE and COM_STMT_SEND_LONG_DATA don't return anything. | ||
| 2090 | COM_PING only discloses information that the server is running, | ||
| 2091 | and that's available through other means. | ||
| 2092 | COM_QUIT should work even for expired statements. | ||
| 2093 | */ | ||
| 2094 |
5/6✓ Branch 0 taken 11178502 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 210 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 11178499 times.
|
22357249 | if (unlikely(thd->security_context()->password_expired() && |
| 2095 |
2/4✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
|
39 | command != COM_QUERY && command != COM_STMT_CLOSE && |
| 2096 |
3/4✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 38 times.
|
39 | command != COM_STMT_SEND_LONG_DATA && command != COM_PING && |
| 2097 |
4/6✓ Branch 0 taken 249 times.
✓ Branch 1 taken 11178253 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
11178751 | command != COM_QUIT && command != COM_STMT_PREPARE && |
| 2098 | command != COM_STMT_EXECUTE)) { | ||
| 2099 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_MUST_CHANGE_PASSWORD, MYF(0)); |
| 2100 | 1 | goto done; | |
| 2101 | } | ||
| 2102 | |||
| 2103 |
3/4✓ Branch 0 taken 11178512 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11178508 times.
|
11178365 | if (mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_COMMAND_START), command, |
| 2104 |
1/2✓ Branch 0 taken 11178462 times.
✗ Branch 1 not taken.
|
11178499 | Command_names::str_global(command).c_str())) { |
| 2105 | 4 | goto done; | |
| 2106 | } | ||
| 2107 | |||
| 2108 |
24/25✓ Branch 0 taken 2635 times.
✓ Branch 1 taken 7125 times.
✓ Branch 2 taken 1286 times.
✓ Branch 3 taken 2157 times.
✓ Branch 4 taken 442 times.
✓ Branch 5 taken 235 times.
✓ Branch 6 taken 5174 times.
✓ Branch 7 taken 1815 times.
✓ Branch 8 taken 496 times.
✓ Branch 9 taken 4753 times.
✓ Branch 10 taken 4198 times.
✓ Branch 11 taken 57 times.
✓ Branch 12 taken 11022637 times.
✓ Branch 13 taken 14 times.
✓ Branch 14 taken 117655 times.
✓ Branch 15 taken 2253 times.
✓ Branch 16 taken 4925 times.
✓ Branch 17 taken 25 times.
✓ Branch 18 taken 28 times.
✓ Branch 19 taken 389 times.
✓ Branch 20 taken 2 times.
✓ Branch 21 taken 38 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 168 times.
|
11178508 | switch (command) { |
| 2109 | 2635 | case COM_INIT_DB: { | |
| 2110 | LEX_STRING tmp; | ||
| 2111 | 2635 | thd->status_var.com_stat[SQLCOM_CHANGE_DB]++; | |
| 2112 | 2635 | thd->convert_string(&tmp, system_charset_info, | |
| 2113 | 2635 | com_data->com_init_db.db_name, | |
| 2114 |
1/2✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
|
2635 | com_data->com_init_db.length, thd->charset()); |
| 2115 | |||
| 2116 | 2635 | LEX_CSTRING tmp_cstr = {tmp.str, tmp.length}; | |
| 2117 |
3/4✓ Branch 0 taken 2635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2614 times.
✓ Branch 3 taken 21 times.
|
2635 | if (!mysql_change_db(thd, tmp_cstr, false)) { |
| 2118 |
1/2✓ Branch 0 taken 2614 times.
✗ Branch 1 not taken.
|
2614 | query_logger.general_log_write(thd, command, thd->db().str, |
| 2119 | 2614 | thd->db().length); | |
| 2120 |
1/2✓ Branch 0 taken 2614 times.
✗ Branch 1 not taken.
|
2614 | my_ok(thd); |
| 2121 | } | ||
| 2122 | 2635 | break; | |
| 2123 | } | ||
| 2124 | 7125 | case COM_REGISTER_SLAVE: { | |
| 2125 | // TODO: access of protocol_classic should be removed | ||
| 2126 |
5/8✓ Branch 0 taken 7125 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7125 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7125 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7041 times.
✓ Branch 7 taken 84 times.
|
7125 | if (!register_replica(thd, thd->get_protocol_classic()->get_raw_packet(), |
| 2127 | thd->get_protocol_classic()->get_packet_length())) | ||
| 2128 |
1/2✓ Branch 0 taken 7041 times.
✗ Branch 1 not taken.
|
7041 | my_ok(thd); |
| 2129 | 7125 | break; | |
| 2130 | } | ||
| 2131 | 1286 | case COM_RESET_CONNECTION: { | |
| 2132 | 1286 | thd->status_var.com_other++; | |
| 2133 | #ifdef WITH_WSREP | ||
| 2134 |
1/2✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
|
1286 | wsrep_after_command_ignore_result(thd); |
| 2135 |
1/2✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
|
1286 | wsrep_close(thd); |
| 2136 | #endif /* WITH_WSREP */ | ||
| 2137 |
1/2✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
|
1286 | thd->cleanup_connection(); |
| 2138 | #ifdef WITH_WSREP | ||
| 2139 |
1/2✓ Branch 0 taken 1285 times.
✗ Branch 1 not taken.
|
1286 | wsrep_open(thd); |
| 2140 |
1/2✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
|
1285 | wsrep_before_command(thd); |
| 2141 | #endif /* WITH_WSREP */ | ||
| 2142 |
1/2✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
|
1286 | my_ok(thd); |
| 2143 | 1286 | break; | |
| 2144 | } | ||
| 2145 | 2157 | case COM_CLONE: { | |
| 2146 | 2157 | thd->status_var.com_other++; | |
| 2147 | |||
| 2148 | /* Try loading clone plugin */ | ||
| 2149 |
1/2✓ Branch 0 taken 2158 times.
✗ Branch 1 not taken.
|
4314 | clone_cmd = new (thd->mem_root) Sql_cmd_clone(); |
| 2150 | |||
| 2151 |
6/8✓ Branch 0 taken 2157 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2158 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 2153 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 2153 times.
|
2157 | if (clone_cmd && clone_cmd->load(thd)) { |
| 2152 | 5 | clone_cmd = nullptr; | |
| 2153 | } | ||
| 2154 | |||
| 2155 | 2158 | thd->lex->m_sql_cmd = clone_cmd; | |
| 2156 | 2158 | thd->lex->sql_command = SQLCOM_CLONE; | |
| 2157 | |||
| 2158 | 2158 | break; | |
| 2159 | } | ||
| 2160 | 442 | case COM_SUBSCRIBE_GROUP_REPLICATION_STREAM: { | |
| 2161 | 442 | Security_context *sctx = thd->security_context(); | |
| 2162 |
1/2✓ Branch 0 taken 442 times.
✗ Branch 1 not taken.
|
442 | if (!sctx->has_global_grant(STRING_WITH_LEN("GROUP_REPLICATION_STREAM")) |
| 2163 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 442 times.
|
442 | .first) { |
| 2164 | ✗ | my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), ""); | |
| 2165 | ✗ | error = true; | |
| 2166 | ✗ | break; | |
| 2167 | } | ||
| 2168 | |||
| 2169 |
6/8✓ Branch 0 taken 442 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 442 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 368 times.
✓ Branch 6 taken 74 times.
✓ Branch 7 taken 368 times.
|
442 | if (!error && get_gr_incoming_connection() == nullptr) { |
| 2170 |
1/2✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
|
74 | my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); |
| 2171 | 74 | error = true; | |
| 2172 | 74 | break; | |
| 2173 | } | ||
| 2174 | |||
| 2175 |
1/2✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
|
368 | my_ok(thd); |
| 2176 | |||
| 2177 | 368 | break; | |
| 2178 | } | ||
| 2179 | 235 | case COM_CHANGE_USER: { | |
| 2180 | /* | ||
| 2181 | LOCK_thd_security_ctx protects the THD's security-context from | ||
| 2182 | inspection by SHOW PROCESSLIST while we're updating it. Nested | ||
| 2183 | acquiring of LOCK_thd_data is fine (see below). | ||
| 2184 | */ | ||
| 2185 | 235 | MUTEX_LOCK(grd_secctx, &thd->LOCK_thd_security_ctx); | |
| 2186 | |||
| 2187 | int auth_rc; | ||
| 2188 | 235 | thd->status_var.com_other++; | |
| 2189 | |||
| 2190 | #ifdef WITH_WSREP | ||
| 2191 |
1/2✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
|
235 | wsrep_after_command_ignore_result(thd); |
| 2192 |
1/2✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
|
235 | wsrep_close(thd); |
| 2193 | #endif /* WITH_WSREP */ | ||
| 2194 | |||
| 2195 |
1/2✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
|
235 | thd->cleanup_connection(); |
| 2196 | |||
| 2197 | #ifdef WITH_WSREP | ||
| 2198 |
1/2✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
|
235 | wsrep_open(thd); |
| 2199 |
1/2✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
|
235 | wsrep_before_command(thd); |
| 2200 | #endif /* WITH_WSREP */ | ||
| 2201 | |||
| 2202 | USER_CONN *save_user_connect = | ||
| 2203 | 235 | const_cast<USER_CONN *>(thd->get_user_connect()); | |
| 2204 | 235 | LEX_CSTRING save_db = thd->db(); | |
| 2205 |
1/2✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
|
235 | Security_context save_security_ctx(*(thd->security_context())); |
| 2206 | |||
| 2207 |
1/2✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
|
235 | auth_rc = acl_authenticate(thd, COM_CHANGE_USER); |
| 2208 |
1/2✓ Branch 0 taken 235 times.
✗ Branch 1 not taken.
|
235 | auth_rc |= mysql_audit_notify( |
| 2209 | thd, AUDIT_EVENT(MYSQL_AUDIT_CONNECTION_CHANGE_USER)); | ||
| 2210 |
2/2✓ Branch 0 taken 65 times.
✓ Branch 1 taken 170 times.
|
235 | if (auth_rc) { |
| 2211 |
1/2✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
|
65 | *thd->security_context() = save_security_ctx; |
| 2212 |
1/2✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
|
65 | thd->set_user_connect(save_user_connect); |
| 2213 |
1/2✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
|
65 | thd->reset_db(save_db); |
| 2214 | |||
| 2215 |
1/2✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
|
65 | my_error(ER_ACCESS_DENIED_CHANGE_USER_ERROR, MYF(0), |
| 2216 |
1/2✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
|
65 | thd->security_context()->user().str, |
| 2217 |
1/2✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
|
65 | thd->security_context()->host_or_ip().str, |
| 2218 |
4/6✓ Branch 0 taken 29 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
|
65 | (thd->password ? ER_THD(thd, ER_YES) : ER_THD(thd, ER_NO))); |
| 2219 | 65 | thd->killed = THD::KILL_CONNECTION; | |
| 2220 | 65 | error = true; | |
| 2221 | } else { | ||
| 2222 | #ifdef HAVE_PSI_THREAD_INTERFACE | ||
| 2223 | /* we've authenticated new user */ | ||
| 2224 |
1/2✓ Branch 0 taken 170 times.
✗ Branch 1 not taken.
|
170 | PSI_THREAD_CALL(notify_session_change_user)(thd->get_psi()); |
| 2225 | #endif /* HAVE_PSI_THREAD_INTERFACE */ | ||
| 2226 | |||
| 2227 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 170 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
170 | if (save_user_connect) decrease_user_connections(save_user_connect); |
| 2228 |
1/2✓ Branch 0 taken 170 times.
✗ Branch 1 not taken.
|
170 | mysql_mutex_lock(&thd->LOCK_thd_data); |
| 2229 |
1/2✓ Branch 0 taken 170 times.
✗ Branch 1 not taken.
|
170 | my_free(const_cast<char *>(save_db.str)); |
| 2230 | 170 | save_db = NULL_CSTR; | |
| 2231 |
1/2✓ Branch 0 taken 170 times.
✗ Branch 1 not taken.
|
170 | mysql_mutex_unlock(&thd->LOCK_thd_data); |
| 2232 | } | ||
| 2233 | 235 | break; | |
| 2234 | 235 | } | |
| 2235 | 5174 | case COM_STMT_EXECUTE: { | |
| 2236 | /* Clear possible warnings from the previous command */ | ||
| 2237 |
1/2✓ Branch 0 taken 5174 times.
✗ Branch 1 not taken.
|
5174 | thd->reset_for_next_command(); |
| 2238 | |||
| 2239 | 5174 | Prepared_statement *stmt = nullptr; | |
| 2240 |
3/4✓ Branch 0 taken 5174 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5165 times.
✓ Branch 3 taken 9 times.
|
5174 | if (!mysql_stmt_precheck(thd, com_data, command, &stmt)) { |
| 2241 | 5165 | PS_PARAM *parameters = com_data->com_stmt_execute.parameters; | |
| 2242 | 5165 | copy_bind_parameter_values(thd, parameters, | |
| 2243 |
1/2✓ Branch 0 taken 5165 times.
✗ Branch 1 not taken.
|
5165 | com_data->com_stmt_execute.parameter_count); |
| 2244 | |||
| 2245 | 5165 | mysqld_stmt_execute(thd, stmt, com_data->com_stmt_execute.has_new_types, | |
| 2246 |
1/2✓ Branch 0 taken 5165 times.
✗ Branch 1 not taken.
|
5165 | com_data->com_stmt_execute.open_cursor, parameters); |
| 2247 | #ifdef WITH_WSREP | ||
| 2248 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5164 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
5165 | if (WSREP_ON) { |
| 2249 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | (void)wsrep_after_statement(thd); |
| 2250 | } | ||
| 2251 | #endif /* WITH_WSREP */ | ||
| 2252 | 5165 | thd->bind_parameter_values = nullptr; | |
| 2253 | 5165 | thd->bind_parameter_values_count = 0; | |
| 2254 | } | ||
| 2255 | 5174 | break; | |
| 2256 | } | ||
| 2257 | 1815 | case COM_STMT_FETCH: { | |
| 2258 | /* Clear possible warnings from the previous command */ | ||
| 2259 |
1/2✓ Branch 0 taken 1815 times.
✗ Branch 1 not taken.
|
1815 | thd->reset_for_next_command(); |
| 2260 | |||
| 2261 | 1815 | Prepared_statement *stmt = nullptr; | |
| 2262 |
3/4✓ Branch 0 taken 1815 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1813 times.
✓ Branch 3 taken 2 times.
|
1815 | if (!mysql_stmt_precheck(thd, com_data, command, &stmt)) |
| 2263 |
1/2✓ Branch 0 taken 1813 times.
✗ Branch 1 not taken.
|
1813 | mysqld_stmt_fetch(thd, stmt, com_data->com_stmt_fetch.num_rows); |
| 2264 | |||
| 2265 | 1815 | break; | |
| 2266 | } | ||
| 2267 | 496 | case COM_STMT_SEND_LONG_DATA: { | |
| 2268 | Prepared_statement *stmt; | ||
| 2269 | 496 | thd->get_stmt_da()->disable_status(); | |
| 2270 |
3/4✓ Branch 0 taken 496 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 492 times.
✓ Branch 3 taken 4 times.
|
496 | if (!mysql_stmt_precheck(thd, com_data, command, &stmt)) |
| 2271 | 492 | mysql_stmt_get_longdata(thd, stmt, | |
| 2272 | 492 | com_data->com_stmt_send_long_data.param_number, | |
| 2273 | 492 | com_data->com_stmt_send_long_data.longdata, | |
| 2274 |
1/2✓ Branch 0 taken 492 times.
✗ Branch 1 not taken.
|
492 | com_data->com_stmt_send_long_data.length); |
| 2275 | 496 | break; | |
| 2276 | } | ||
| 2277 | 4753 | case COM_STMT_PREPARE: { | |
| 2278 | /* Clear possible warnings from the previous command */ | ||
| 2279 |
1/2✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
|
4753 | thd->reset_for_next_command(); |
| 2280 | 4753 | Prepared_statement *stmt = nullptr; | |
| 2281 | |||
| 2282 |
2/20✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4753 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
4753 | DBUG_EXECUTE_IF("parser_stmt_to_error_log", { |
| 2283 | LogErr(INFORMATION_LEVEL, ER_PARSER_TRACE, | ||
| 2284 | com_data->com_stmt_prepare.query); | ||
| 2285 | }); | ||
| 2286 |
2/20✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4753 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
4753 | DBUG_EXECUTE_IF("parser_stmt_to_error_log_with_system_prio", { |
| 2287 | LogErr(SYSTEM_LEVEL, ER_PARSER_TRACE, com_data->com_stmt_prepare.query); | ||
| 2288 | }); | ||
| 2289 | |||
| 2290 |
2/4✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4753 times.
✗ Branch 3 not taken.
|
4753 | if (!mysql_stmt_precheck(thd, com_data, command, &stmt)) |
| 2291 | 4753 | mysqld_stmt_prepare(thd, com_data->com_stmt_prepare.query, | |
| 2292 |
1/2✓ Branch 0 taken 4753 times.
✗ Branch 1 not taken.
|
4753 | com_data->com_stmt_prepare.length, stmt); |
| 2293 | 4753 | break; | |
| 2294 | } | ||
| 2295 | 4198 | case COM_STMT_CLOSE: { | |
| 2296 | 4198 | Prepared_statement *stmt = nullptr; | |
| 2297 | 4198 | thd->get_stmt_da()->disable_status(); | |
| 2298 |
3/4✓ Branch 0 taken 4198 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4196 times.
✓ Branch 3 taken 2 times.
|
4198 | if (!mysql_stmt_precheck(thd, com_data, command, &stmt)) |
| 2299 |
1/2✓ Branch 0 taken 4196 times.
✗ Branch 1 not taken.
|
4196 | mysqld_stmt_close(thd, stmt); |
| 2300 | 4198 | break; | |
| 2301 | } | ||
| 2302 | 57 | case COM_STMT_RESET: { | |
| 2303 | /* Clear possible warnings from the previous command */ | ||
| 2304 |
1/2✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
|
57 | thd->reset_for_next_command(); |
| 2305 | |||
| 2306 | 57 | Prepared_statement *stmt = nullptr; | |
| 2307 |
3/4✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 2 times.
|
57 | if (!mysql_stmt_precheck(thd, com_data, command, &stmt)) |
| 2308 |
1/2✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
|
55 | mysqld_stmt_reset(thd, stmt); |
| 2309 | 57 | break; | |
| 2310 | } | ||
| 2311 | 11022637 | case COM_QUERY: { | |
| 2312 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11022637 times.
|
11022637 | assert(thd->m_digest == nullptr); |
| 2313 | 11022637 | thd->m_digest = &thd->m_digest_state; | |
| 2314 |
1/2✓ Branch 0 taken 11022589 times.
✗ Branch 1 not taken.
|
11022637 | thd->m_digest->reset(thd->m_token_array, max_digest_length); |
| 2315 | |||
| 2316 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11022934 times.
|
11022934 | if (alloc_query(thd, com_data->com_query.query, |
| 2317 |
1/2✓ Branch 0 taken 11022934 times.
✗ Branch 1 not taken.
|
11022589 | com_data->com_query.length)) |
| 2318 | 11020512 | break; // fatal error is set | |
| 2319 | |||
| 2320 |
2/4✓ Branch 0 taken 11022884 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022886 times.
✗ Branch 3 not taken.
|
11022934 | const char *packet_end = thd->query().str + thd->query().length; |
| 2321 | |||
| 2322 |
2/2✓ Branch 0 taken 226 times.
✓ Branch 1 taken 11022660 times.
|
11022886 | if (opt_general_log_raw) |
| 2323 |
1/2✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
|
226 | query_logger.general_log_write(thd, command, thd->query().str, |
| 2324 |
2/4✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✗ Branch 3 not taken.
|
226 | thd->query().length); |
| 2325 | |||
| 2326 |
6/10✓ Branch 0 taken 11022611 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022710 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 190 times.
✓ Branch 5 taken 11022520 times.
✓ Branch 6 taken 190 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 190 times.
✗ Branch 9 not taken.
|
11022886 | DBUG_PRINT("query", ("%-.4096s", thd->query().str)); |
| 2327 | |||
| 2328 | #if defined(ENABLED_PROFILING) | ||
| 2329 |
3/6✓ Branch 0 taken 11022821 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022844 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11022787 times.
✗ Branch 5 not taken.
|
11022710 | thd->profiling->set_query_source(thd->query().str, thd->query().length); |
| 2330 | #endif | ||
| 2331 | |||
| 2332 |
1/2✓ Branch 0 taken 11022827 times.
✗ Branch 1 not taken.
|
11022787 | const LEX_CSTRING orig_query = thd->query(); |
| 2333 | |||
| 2334 |
1/2✓ Branch 0 taken 11022783 times.
✗ Branch 1 not taken.
|
11022827 | Parser_state parser_state; |
| 2335 |
5/8✓ Branch 0 taken 11022829 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022826 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11022653 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 11022652 times.
|
11022783 | if (parser_state.init(thd, thd->query().str, thd->query().length)) break; |
| 2336 | |||
| 2337 | 11022652 | parser_state.m_input.m_has_digest = true; | |
| 2338 | |||
| 2339 | // we produce digest if it's not explicitly turned off | ||
| 2340 | // by setting maximum digest length to zero | ||
| 2341 |
3/4✓ Branch 0 taken 11022466 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11022456 times.
✓ Branch 3 taken 10 times.
|
11022652 | if (get_max_digest_length() != 0) |
| 2342 | 11022456 | parser_state.m_input.m_compute_digest = true; | |
| 2343 | |||
| 2344 | // Initially, prepare and optimize the statement for the primary | ||
| 2345 | // storage engine. If an eligible secondary storage engine is | ||
| 2346 | // found, the statement may be reprepared for the secondary | ||
| 2347 | // storage engine later. | ||
| 2348 | 11022466 | const auto saved_secondary_engine = thd->secondary_engine_optimization(); | |
| 2349 | 11022705 | thd->set_secondary_engine_optimization( | |
| 2350 | Secondary_engine_optimization::PRIMARY_TENTATIVELY); | ||
| 2351 | |||
| 2352 | 11022721 | copy_bind_parameter_values(thd, com_data->com_query.parameters, | |
| 2353 |
1/2✓ Branch 0 taken 11022654 times.
✗ Branch 1 not taken.
|
11022721 | com_data->com_query.parameter_count); |
| 2354 | |||
| 2355 | #ifdef WITH_WSREP | ||
| 2356 |
3/4✓ Branch 0 taken 162901 times.
✓ Branch 1 taken 10859753 times.
✓ Branch 2 taken 162901 times.
✗ Branch 3 not taken.
|
11022654 | if (WSREP_ON) { |
| 2357 |
2/4✓ Branch 0 taken 162897 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 162897 times.
|
162901 | if (wsrep_dispatch_sql_command(thd, thd->query().str, |
| 2358 |
2/4✓ Branch 0 taken 162901 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 162901 times.
✗ Branch 3 not taken.
|
162901 | thd->query().length, &parser_state, |
| 2359 | false)) { | ||
| 2360 | ✗ | WSREP_DEBUG("Deadlock error for: %s", thd->query().str); | |
| 2361 | ✗ | mysql_mutex_lock(&thd->LOCK_wsrep_thd); | |
| 2362 | ✗ | thd->killed = THD::NOT_KILLED; | |
| 2363 | ✗ | thd->wsrep_retry_counter = 0; | |
| 2364 | ✗ | mysql_mutex_unlock(&thd->LOCK_wsrep_thd); | |
| 2365 | ✗ | goto dispatch_end; | |
| 2366 | } | ||
| 2367 | } else { | ||
| 2368 |
1/2✓ Branch 0 taken 10857789 times.
✗ Branch 1 not taken.
|
10859753 | dispatch_sql_command(thd, &parser_state, false); |
| 2369 | } | ||
| 2370 | #else | ||
| 2371 | dispatch_sql_command(thd, &parser_state, false); | ||
| 2372 | #endif /* WITH_WSREP */ | ||
| 2373 | |||
| 2374 | // Check if the statement failed and needs to be restarted in | ||
| 2375 | // another storage engine. | ||
| 2376 | 11020686 | check_secondary_engine_statement(thd, &parser_state, orig_query.str, | |
| 2377 |
1/2✓ Branch 0 taken 11020940 times.
✗ Branch 1 not taken.
|
11020686 | orig_query.length); |
| 2378 | |||
| 2379 | 11020940 | thd->set_secondary_engine_optimization(saved_secondary_engine); | |
| 2380 | |||
| 2381 |
12/22✓ Branch 0 taken 11020704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 11020258 times.
✓ Branch 4 taken 446 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 446 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 446 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 446 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 446 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 446 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 446 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 446 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 446 times.
✗ Branch 21 not taken.
|
11020614 | DBUG_EXECUTE_IF("parser_stmt_to_error_log", { |
| 2382 | LogErr(INFORMATION_LEVEL, ER_PARSER_TRACE, thd->query().str); | ||
| 2383 | }); | ||
| 2384 |
12/22✓ Branch 0 taken 11020546 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 11020447 times.
✓ Branch 4 taken 99 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 99 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 99 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 99 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 99 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 99 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 99 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 99 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 99 times.
✗ Branch 21 not taken.
|
11020704 | DBUG_EXECUTE_IF("parser_stmt_to_error_log_with_system_prio", { |
| 2385 | LogErr(SYSTEM_LEVEL, ER_PARSER_TRACE, thd->query().str); | ||
| 2386 | }); | ||
| 2387 | |||
| 2388 |
6/6✓ Branch 0 taken 11101100 times.
✓ Branch 1 taken 290 times.
✓ Branch 2 taken 81182 times.
✓ Branch 3 taken 11019918 times.
✓ Branch 4 taken 80932 times.
✓ Branch 5 taken 11020458 times.
|
11182652 | while (!thd->killed && (parser_state.m_lip.found_semicolon != nullptr) && |
| 2389 |
3/4✓ Branch 0 taken 81182 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80932 times.
✓ Branch 3 taken 250 times.
|
81182 | !thd->is_error()) { |
| 2390 | /* | ||
| 2391 | Multiple queries exits, execute them individually | ||
| 2392 | */ | ||
| 2393 | 80932 | const char *beginning_of_next_stmt = parser_state.m_lip.found_semicolon; | |
| 2394 | |||
| 2395 | /* Finalize server status flags after executing a statement. */ | ||
| 2396 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->update_slow_query_status(); |
| 2397 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->send_statement_status(); |
| 2398 | |||
| 2399 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | const std::string &cn = Command_names::str_global(command); |
| 2400 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 80932 times.
✓ Branch 2 taken 80932 times.
✗ Branch 3 not taken.
|
161864 | mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_STATUS), |
| 2401 | 80932 | thd->get_stmt_da()->is_error() | |
| 2402 | ✗ | ? thd->get_stmt_da()->mysql_errno() | |
| 2403 | : 0, | ||
| 2404 | cn.c_str(), cn.length()); | ||
| 2405 | |||
| 2406 | 80932 | size_t length = | |
| 2407 | 80932 | static_cast<size_t>(packet_end - beginning_of_next_stmt); | |
| 2408 | |||
| 2409 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | log_slow_statement(thd); |
| 2410 | |||
| 2411 | 80932 | thd->reset_copy_status_var(); | |
| 2412 | |||
| 2413 | /* Remove garbage at start of query */ | ||
| 2414 |
3/4✓ Branch 0 taken 96698 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15766 times.
✓ Branch 3 taken 80932 times.
|
193396 | while (length > 0 && |
| 2415 |
2/2✓ Branch 0 taken 15766 times.
✓ Branch 1 taken 80932 times.
|
96698 | my_isspace(thd->charset(), *beginning_of_next_stmt)) { |
| 2416 | 15766 | beginning_of_next_stmt++; | |
| 2417 | 15766 | length--; | |
| 2418 | } | ||
| 2419 | |||
| 2420 | /* PSI end */ | ||
| 2421 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); |
| 2422 | 80932 | thd->m_statement_psi = nullptr; | |
| 2423 | 80932 | thd->m_digest = nullptr; | |
| 2424 | |||
| 2425 | /* SHOW PROFILE end */ | ||
| 2426 | #if defined(ENABLED_PROFILING) | ||
| 2427 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->profiling->finish_current_query(); |
| 2428 | #endif | ||
| 2429 | |||
| 2430 | /* SHOW PROFILE begin */ | ||
| 2431 | #if defined(ENABLED_PROFILING) | ||
| 2432 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->profiling->start_new_query("continuing"); |
| 2433 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->profiling->set_query_source(beginning_of_next_stmt, length); |
| 2434 | #endif | ||
| 2435 | |||
| 2436 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | mysql_thread_set_secondary_engine(false); |
| 2437 | |||
| 2438 | /* PSI begin */ | ||
| 2439 | 80932 | thd->m_digest = &thd->m_digest_state; | |
| 2440 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->m_digest->reset(thd->m_token_array, max_digest_length); |
| 2441 | |||
| 2442 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->m_statement_psi = MYSQL_START_STATEMENT( |
| 2443 | &thd->m_statement_state, com_statement_info[command].m_key, | ||
| 2444 | thd->db().str, thd->db().length, thd->charset(), nullptr); | ||
| 2445 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | THD_STAGE_INFO(thd, stage_starting); |
| 2446 | |||
| 2447 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->set_query(beginning_of_next_stmt, length); |
| 2448 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | thd->set_query_id(next_query_id()); |
| 2449 | /* | ||
| 2450 | Count each statement from the client. | ||
| 2451 | */ | ||
| 2452 | 80932 | thd->status_var.questions++; | |
| 2453 | #ifdef WITH_WSREP | ||
| 2454 |
6/10✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 80929 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 80929 times.
✗ Branch 9 not taken.
|
80932 | if (!WSREP(thd)) thd->set_time(); /* Reset the query start time. */ |
| 2455 |
1/2✓ Branch 0 taken 80932 times.
✗ Branch 1 not taken.
|
80932 | parser_state.reset(beginning_of_next_stmt, length); |
| 2456 | 80932 | thd->set_secondary_engine_optimization( | |
| 2457 | Secondary_engine_optimization::PRIMARY_TENTATIVELY); | ||
| 2458 | |||
| 2459 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 80929 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
80932 | if (WSREP_ON) { |
| 2460 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
3 | if (wsrep_dispatch_sql_command(thd, beginning_of_next_stmt, length, |
| 2461 | &parser_state, false)) { | ||
| 2462 | ✗ | WSREP_DEBUG("Deadlock error for: %s", thd->query().str); | |
| 2463 | ✗ | mysql_mutex_lock(&thd->LOCK_wsrep_thd); | |
| 2464 | ✗ | thd->killed = THD::NOT_KILLED; | |
| 2465 | ✗ | thd->wsrep_retry_counter = 0; | |
| 2466 | ✗ | mysql_mutex_unlock(&thd->LOCK_wsrep_thd); | |
| 2467 | |||
| 2468 | ✗ | goto dispatch_end; | |
| 2469 | } | ||
| 2470 | } else { | ||
| 2471 |
1/2✓ Branch 0 taken 80921 times.
✗ Branch 1 not taken.
|
80929 | dispatch_sql_command(thd, &parser_state, false); |
| 2472 | } | ||
| 2473 | #else | ||
| 2474 | thd->set_time(); /* Reset the query start time. */ | ||
| 2475 | parser_state.reset(beginning_of_next_stmt, length); | ||
| 2476 | thd->set_secondary_engine_optimization( | ||
| 2477 | Secondary_engine_optimization::PRIMARY_TENTATIVELY); | ||
| 2478 | /* TODO: set thd->lex->sql_command to SQLCOM_END here */ | ||
| 2479 | dispatch_sql_command(thd, &parser_state, false); | ||
| 2480 | #endif /* WITH_WSREP */ | ||
| 2481 | |||
| 2482 |
1/2✓ Branch 0 taken 80924 times.
✗ Branch 1 not taken.
|
80924 | check_secondary_engine_statement(thd, &parser_state, |
| 2483 | beginning_of_next_stmt, length); | ||
| 2484 | |||
| 2485 | 80924 | thd->set_secondary_engine_optimization(saved_secondary_engine); | |
| 2486 | } | ||
| 2487 | |||
| 2488 | 11020458 | thd->bind_parameter_values = nullptr; | |
| 2489 | 11020458 | thd->bind_parameter_values_count = 0; | |
| 2490 | |||
| 2491 | /* Need to set error to true for graceful shutdown */ | ||
| 2492 |
6/6✓ Branch 0 taken 7779 times.
✓ Branch 1 taken 11012679 times.
✓ Branch 2 taken 7778 times.
✓ Branch 3 taken 218 times.
✓ Branch 4 taken 7778 times.
✓ Branch 5 taken 11012897 times.
|
11028454 | if ((thd->lex->sql_command == SQLCOM_SHUTDOWN) && |
| 2493 | 7779 | (thd->get_stmt_da()->is_ok())) | |
| 2494 | 7778 | error = true; | |
| 2495 | |||
| 2496 |
5/8✓ Branch 0 taken 11020817 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11020893 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 203 times.
✓ Branch 5 taken 11020690 times.
✓ Branch 6 taken 213 times.
✗ Branch 7 not taken.
|
11020675 | DBUG_PRINT("info", ("query ready")); |
| 2497 | 11020903 | break; | |
| 2498 |
1/2✓ Branch 0 taken 11020512 times.
✗ Branch 1 not taken.
|
11020904 | } |
| 2499 | 14 | case COM_FIELD_LIST: // This isn't actually needed | |
| 2500 | { | ||
| 2501 | char *fields; | ||
| 2502 | /* Locked closure of all tables */ | ||
| 2503 | LEX_STRING table_name; | ||
| 2504 | LEX_STRING db; | ||
| 2505 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | push_deprecated_warn(thd, "COM_FIELD_LIST", |
| 2506 | "SHOW COLUMNS FROM statement"); | ||
| 2507 | /* | ||
| 2508 | SHOW statements should not add the used tables to the list of tables | ||
| 2509 | used in a transaction. | ||
| 2510 | */ | ||
| 2511 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint(); |
| 2512 | |||
| 2513 | 14 | thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]++; | |
| 2514 |
2/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
|
14 | if (thd->copy_db_to(&db.str, &db.length)) break; |
| 2515 | 14 | thd->convert_string(&table_name, system_charset_info, | |
| 2516 | 14 | (char *)com_data->com_field_list.table_name, | |
| 2517 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | com_data->com_field_list.table_name_length, |
| 2518 | thd->charset()); | ||
| 2519 | Ident_name_check ident_check_status = | ||
| 2520 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | check_table_name(table_name.str, table_name.length); |
| 2521 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | if (ident_check_status == Ident_name_check::WRONG) { |
| 2522 | /* this is OK due to convert_string() null-terminating the string */ | ||
| 2523 | ✗ | my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str); | |
| 2524 | ✗ | break; | |
| 2525 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | } else if (ident_check_status == Ident_name_check::TOO_LONG) { |
| 2526 | ✗ | my_error(ER_TOO_LONG_IDENT, MYF(0), table_name.str); | |
| 2527 | ✗ | break; | |
| 2528 | } | ||
| 2529 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | mysql_reset_thd_for_next_command(thd); |
| 2530 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | lex_start(thd); |
| 2531 | /* Must be before we init the table list. */ | ||
| 2532 |
5/8✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 14 times.
|
14 | if (lower_case_table_names && !is_infoschema_db(db.str, db.length)) |
| 2533 | ✗ | table_name.length = my_casedn_str(files_charset_info, table_name.str); | |
| 2534 | 14 | TABLE_LIST table_list(db.str, db.length, table_name.str, | |
| 2535 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | table_name.length, table_name.str, TL_READ); |
| 2536 | /* | ||
| 2537 | Init TABLE_LIST members necessary when the undelrying | ||
| 2538 | table is view. | ||
| 2539 | */ | ||
| 2540 | 14 | table_list.query_block = thd->lex->query_block; | |
| 2541 | 14 | thd->lex->query_block->table_list.link_in_list(&table_list, | |
| 2542 | &table_list.next_local); | ||
| 2543 | 14 | thd->lex->add_to_query_tables(&table_list); | |
| 2544 | |||
| 2545 |
3/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 12 times.
|
14 | if (is_infoschema_db(table_list.db, table_list.db_length)) { |
| 2546 | ST_SCHEMA_TABLE *schema_table = | ||
| 2547 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | find_schema_table(thd, table_list.alias); |
| 2548 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (schema_table) table_list.schema_table = schema_table; |
| 2549 | } | ||
| 2550 | |||
| 2551 | 14 | if (!(fields = | |
| 2552 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | (char *)thd->memdup(com_data->com_field_list.query, |
| 2553 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | com_data->com_field_list.query_length))) |
| 2554 | ✗ | break; | |
| 2555 | // Don't count end \0 | ||
| 2556 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | thd->set_query(fields, com_data->com_field_list.query_length - 1); |
| 2557 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | query_logger.general_log_print(thd, command, "%s %s", |
| 2558 | table_list.table_name, fields); | ||
| 2559 | |||
| 2560 |
2/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
|
14 | if (open_temporary_tables(thd, &table_list)) break; |
| 2561 | |||
| 2562 |
2/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
|
14 | if (check_table_access(thd, SELECT_ACL, &table_list, true, UINT_MAX, |
| 2563 | false)) | ||
| 2564 | ✗ | break; | |
| 2565 | |||
| 2566 | 14 | thd->lex->sql_command = SQLCOM_SHOW_FIELDS; | |
| 2567 | // See comment in opt_trace_disable_if_no_security_context_access() | ||
| 2568 | 14 | Opt_trace_start ots(thd, &table_list, thd->lex->sql_command, nullptr, | |
| 2569 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | nullptr, 0, nullptr, nullptr); |
| 2570 | |||
| 2571 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | mysqld_list_fields(thd, &table_list, fields); |
| 2572 | |||
| 2573 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | thd->lex->cleanup(thd, true); |
| 2574 | /* No need to rollback statement transaction, it's not started. */ | ||
| 2575 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT)); |
| 2576 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | close_thread_tables(thd); |
| 2577 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | thd->mdl_context.rollback_to_savepoint(mdl_savepoint); |
| 2578 | |||
| 2579 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | if (thd->transaction_rollback_request) { |
| 2580 | /* | ||
| 2581 | Transaction rollback was requested since MDL deadlock was | ||
| 2582 | discovered while trying to open tables. Rollback transaction | ||
| 2583 | in all storage engines including binary log and release all | ||
| 2584 | locks. | ||
| 2585 | */ | ||
| 2586 | ✗ | trans_rollback_implicit(thd); | |
| 2587 | ✗ | thd->mdl_context.release_transactional_locks(); | |
| 2588 | } | ||
| 2589 | |||
| 2590 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | thd->cleanup_after_query(); |
| 2591 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | thd->lex->destroy(); |
| 2592 | 14 | break; | |
| 2593 | 14 | } | |
| 2594 | 117655 | case COM_QUIT: | |
| 2595 | /* Prevent results of the form, "n>0 rows sent, 0 bytes sent" */ | ||
| 2596 |
1/2✓ Branch 0 taken 117650 times.
✗ Branch 1 not taken.
|
117655 | thd->set_sent_row_count(0); |
| 2597 | /* We don't calculate statistics for this command */ | ||
| 2598 |
1/2✓ Branch 0 taken 117716 times.
✗ Branch 1 not taken.
|
117650 | query_logger.general_log_print(thd, command, NullS); |
| 2599 | // Don't give 'abort' message | ||
| 2600 | // TODO: access of protocol_classic should be removed | ||
| 2601 |
2/4✓ Branch 0 taken 117716 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117716 times.
✗ Branch 3 not taken.
|
117716 | if (thd->is_classic_protocol()) |
| 2602 |
2/4✓ Branch 0 taken 117716 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117716 times.
✗ Branch 3 not taken.
|
117716 | thd->get_protocol_classic()->get_net()->error = NET_ERROR_UNSET; |
| 2603 | 117716 | thd->get_stmt_da()->disable_status(); // Don't send anything back | |
| 2604 | 117428 | error = true; // End server | |
| 2605 | 117428 | break; | |
| 2606 | 2253 | case COM_BINLOG_DUMP_GTID: | |
| 2607 | // TODO: access of protocol_classic should be removed | ||
| 2608 |
2/4✓ Branch 0 taken 2253 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2251 times.
✗ Branch 3 not taken.
|
4506 | error = com_binlog_dump_gtid( |
| 2609 |
1/2✓ Branch 0 taken 2253 times.
✗ Branch 1 not taken.
|
2253 | thd, (char *)thd->get_protocol_classic()->get_raw_packet(), |
| 2610 | thd->get_protocol_classic()->get_packet_length()); | ||
| 2611 | 2251 | break; | |
| 2612 | 4925 | case COM_BINLOG_DUMP: | |
| 2613 | // TODO: access of protocol_classic should be removed | ||
| 2614 |
2/4✓ Branch 0 taken 4925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4922 times.
✗ Branch 3 not taken.
|
9850 | error = com_binlog_dump( |
| 2615 |
1/2✓ Branch 0 taken 4925 times.
✗ Branch 1 not taken.
|
4925 | thd, (char *)thd->get_protocol_classic()->get_raw_packet(), |
| 2616 | thd->get_protocol_classic()->get_packet_length()); | ||
| 2617 | 4922 | break; | |
| 2618 | 25 | case COM_REFRESH: { | |
| 2619 | int not_used; | ||
| 2620 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | push_deprecated_warn(thd, "COM_REFRESH", "FLUSH statement"); |
| 2621 | /* | ||
| 2622 | Initialize thd->lex since it's used in many base functions, such as | ||
| 2623 | open_tables(). Otherwise, it remains uninitialized and may cause crash | ||
| 2624 | during execution of COM_REFRESH. | ||
| 2625 | */ | ||
| 2626 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | lex_start(thd); |
| 2627 | |||
| 2628 | 25 | thd->status_var.com_stat[SQLCOM_FLUSH]++; | |
| 2629 | 25 | ulong options = (ulong)com_data->com_refresh.options; | |
| 2630 |
2/4✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
|
25 | if (trans_commit_implicit(thd)) break; |
| 2631 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | thd->mdl_context.release_transactional_locks(); |
| 2632 |
2/4✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
|
25 | if (check_global_access(thd, RELOAD_ACL)) break; |
| 2633 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | query_logger.general_log_print(thd, command, NullS); |
| 2634 | #ifndef NDEBUG | ||
| 2635 | 25 | bool debug_simulate = false; | |
| 2636 |
3/4✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 24 times.
|
25 | DBUG_EXECUTE_IF("simulate_detached_thread_refresh", |
| 2637 | debug_simulate = true;); | ||
| 2638 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 24 times.
|
25 | if (debug_simulate) { |
| 2639 | /* | ||
| 2640 | Simulate a reload without a attached thread session. | ||
| 2641 | Provides a environment similar to that of when the | ||
| 2642 | server receives a SIGHUP signal and reloads caches | ||
| 2643 | and flushes tables. | ||
| 2644 | */ | ||
| 2645 | bool res; | ||
| 2646 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | current_thd = nullptr; |
| 2647 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | res = handle_reload_request(nullptr, options | REFRESH_FAST, nullptr, |
| 2648 | ¬_used); | ||
| 2649 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | current_thd = thd; |
| 2650 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (res) break; |
| 2651 | } else | ||
| 2652 | #endif | ||
| 2653 |
2/4✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
|
24 | if (handle_reload_request(thd, options, (TABLE_LIST *)nullptr, |
| 2654 | ¬_used)) | ||
| 2655 | ✗ | break; | |
| 2656 |
2/4✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
|
25 | if (trans_commit_implicit(thd)) break; |
| 2657 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | close_thread_tables(thd); |
| 2658 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | thd->mdl_context.release_transactional_locks(); |
| 2659 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | thd->lex->destroy(); |
| 2660 |
1/2✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
|
25 | my_ok(thd); |
| 2661 | 25 | break; | |
| 2662 | } | ||
| 2663 | 28 | case COM_STATISTICS: { | |
| 2664 | System_status_var current_global_status_var; | ||
| 2665 | ulong uptime; | ||
| 2666 | size_t length [[maybe_unused]]; | ||
| 2667 | ulonglong queries_per_second1000; | ||
| 2668 | char buff[250]; | ||
| 2669 | 28 | size_t buff_len = sizeof(buff); | |
| 2670 | |||
| 2671 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | query_logger.general_log_print(thd, command, NullS); |
| 2672 | 28 | thd->status_var.com_stat[SQLCOM_SHOW_STATUS]++; | |
| 2673 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | mysql_mutex_lock(&LOCK_status); |
| 2674 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | calc_sum_of_all_status(¤t_global_status_var); |
| 2675 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | mysql_mutex_unlock(&LOCK_status); |
| 2676 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
|
28 | if (!(uptime = (ulong)(thd->query_start_in_secs() - server_start_time))) |
| 2677 | ✗ | queries_per_second1000 = 0; | |
| 2678 | else | ||
| 2679 | 28 | queries_per_second1000 = thd->query_id * 1000LL / uptime; | |
| 2680 | |||
| 2681 | 84 | length = snprintf(buff, buff_len - 1, | |
| 2682 | "Uptime: %lu Threads: %d Questions: %lu " | ||
| 2683 | "Slow queries: %llu Opens: %llu Flush tables: %lu " | ||
| 2684 | "Open tables: %u Queries per second avg: %u.%03u", | ||
| 2685 | 28 | uptime, (int)thd_manager->get_thd_count(), | |
| 2686 | 28 | (ulong)thd->query_id, | |
| 2687 | current_global_status_var.long_query_count, | ||
| 2688 | current_global_status_var.opened_tables, | ||
| 2689 | refresh_version, table_cache_manager.cached_tables(), | ||
| 2690 | 28 | (uint)(queries_per_second1000 / 1000), | |
| 2691 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | (uint)(queries_per_second1000 % 1000)); |
| 2692 | // TODO: access of protocol_classic should be removed. | ||
| 2693 | // should be rewritten using store functions | ||
| 2694 |
3/6✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
|
28 | if (thd->get_protocol_classic()->write(pointer_cast<const uchar *>(buff), |
| 2695 | length)) | ||
| 2696 | ✗ | break; | |
| 2697 |
2/4✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
|
28 | if (thd->get_protocol()->flush()) break; |
| 2698 | 28 | thd->get_stmt_da()->disable_status(); | |
| 2699 | 28 | break; | |
| 2700 | } | ||
| 2701 | 389 | case COM_PING: | |
| 2702 | 389 | thd->status_var.com_other++; | |
| 2703 |
1/2✓ Branch 0 taken 389 times.
✗ Branch 1 not taken.
|
389 | my_ok(thd); // Tell client we are alive |
| 2704 | 389 | break; | |
| 2705 | 2 | case COM_PROCESS_INFO: | |
| 2706 | bool global_access; | ||
| 2707 | LEX_CSTRING db_saved; | ||
| 2708 | 2 | thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]++; | |
| 2709 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | push_deprecated_warn(thd, "COM_PROCESS_INFO", |
| 2710 | "SHOW PROCESSLIST statement"); | ||
| 2711 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | global_access = (check_global_access(thd, PROCESS_ACL) == 0); |
| 2712 |
3/8✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
2 | if (!thd->security_context()->priv_user().str[0] && !global_access) break; |
| 2713 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | query_logger.general_log_print(thd, command, NullS); |
| 2714 | 2 | db_saved = thd->db(); | |
| 2715 | |||
| 2716 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
2 | DBUG_EXECUTE_IF("force_db_name_to_null", thd->reset_db(NULL_CSTR);); |
| 2717 | |||
| 2718 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | mysqld_list_processes( |
| 2719 | ✗ | thd, global_access ? NullS : thd->security_context()->priv_user().str, | |
| 2720 | false, false); | ||
| 2721 | |||
| 2722 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
2 | DBUG_EXECUTE_IF("force_db_name_to_null", thd->reset_db(db_saved);); |
| 2723 | 2 | break; | |
| 2724 | 38 | case COM_PROCESS_KILL: { | |
| 2725 |
1/2✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
|
38 | push_deprecated_warn(thd, "COM_PROCESS_KILL", |
| 2726 | "KILL CONNECTION/QUERY statement"); | ||
| 2727 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
|
38 | if (thd_manager->get_thread_id() & (~0xfffffffful)) |
| 2728 | ✗ | my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "thread_id", "mysql_kill()"); | |
| 2729 | else { | ||
| 2730 | 38 | thd->status_var.com_stat[SQLCOM_KILL]++; | |
| 2731 |
1/2✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
|
38 | sql_kill(thd, com_data->com_kill.id, false); |
| 2732 | } | ||
| 2733 | 38 | break; | |
| 2734 | } | ||
| 2735 | ✗ | case COM_SET_OPTION: { | |
| 2736 | ✗ | thd->status_var.com_stat[SQLCOM_SET_OPTION]++; | |
| 2737 | |||
| 2738 | ✗ | switch (com_data->com_set_option.opt_command) { | |
| 2739 | ✗ | case (int)MYSQL_OPTION_MULTI_STATEMENTS_ON: | |
| 2740 | // TODO: access of protocol_classic should be removed | ||
| 2741 | ✗ | thd->get_protocol_classic()->add_client_capability( | |
| 2742 | CLIENT_MULTI_STATEMENTS); | ||
| 2743 | ✗ | my_eof(thd); | |
| 2744 | ✗ | break; | |
| 2745 | ✗ | case (int)MYSQL_OPTION_MULTI_STATEMENTS_OFF: | |
| 2746 | ✗ | thd->get_protocol_classic()->remove_client_capability( | |
| 2747 | CLIENT_MULTI_STATEMENTS); | ||
| 2748 | ✗ | my_eof(thd); | |
| 2749 | ✗ | break; | |
| 2750 | ✗ | default: | |
| 2751 | ✗ | my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); | |
| 2752 | ✗ | break; | |
| 2753 | } | ||
| 2754 | ✗ | break; | |
| 2755 | } | ||
| 2756 | 1 | case COM_DEBUG: | |
| 2757 | 1 | thd->status_var.com_other++; | |
| 2758 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (check_global_access(thd, SUPER_ACL)) break; /* purecov: inspected */ |
| 2759 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | query_logger.general_log_print(thd, command, NullS); |
| 2760 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_eof(thd); |
| 2761 | #ifdef WITH_LOCK_ORDER | ||
| 2762 | LO_dump(); | ||
| 2763 | #endif /* WITH_LOCK_ORDER */ | ||
| 2764 | 1 | break; | |
| 2765 | 168 | case COM_SLEEP: | |
| 2766 | case COM_CONNECT: // Impossible here | ||
| 2767 | case COM_TIME: // Impossible from client | ||
| 2768 | case COM_DELAYED_INSERT: // INSERT DELAYED has been removed. | ||
| 2769 | case COM_END: | ||
| 2770 | default: | ||
| 2771 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
168 | my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); |
| 2772 | 4 | break; | |
| 2773 | } | ||
| 2774 | |||
| 2775 | #ifdef WITH_WSREP | ||
| 2776 | 11175922 | dispatch_end: | |
| 2777 | /* | ||
| 2778 | BF aborted before sending response back to client | ||
| 2779 | */ | ||
| 2780 |
2/2✓ Branch 0 taken 2872 times.
✓ Branch 1 taken 11173523 times.
|
11175922 | if (thd->killed == THD::KILL_QUERY) { |
| 2781 |
1/24✗ Branch 0 not taken.
✓ Branch 1 taken 2872 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
2872 | WSREP_DEBUG("THD is killed at dispatch_end"); |
| 2782 | } | ||
| 2783 |
1/2✓ Branch 0 taken 11176288 times.
✗ Branch 1 not taken.
|
11176395 | wsrep_after_command_before_result(thd); |
| 2784 |
5/6✓ Branch 0 taken 706 times.
✓ Branch 1 taken 11176316 times.
✓ Branch 2 taken 706 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 706 times.
✓ Branch 5 taken 11176316 times.
|
11176994 | if (wsrep_current_error(thd) && |
| 2785 |
3/6✓ Branch 0 taken 706 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 706 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 706 times.
✗ Branch 5 not taken.
|
706 | !(command == COM_STMT_PREPARE || command == COM_STMT_FETCH || |
| 2786 | command == COM_STMT_SEND_LONG_DATA || command == COM_STMT_CLOSE)) { | ||
| 2787 | /* todo: Pass wsrep client state current error to override */ | ||
| 2788 |
1/2✓ Branch 0 taken 705 times.
✗ Branch 1 not taken.
|
706 | wsrep_override_error(thd, wsrep_current_error(thd), |
| 2789 | wsrep_current_error_status(thd)); | ||
| 2790 |
1/2✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
|
705 | WSREP_LOG_THD(thd, "leave"); |
| 2791 | } | ||
| 2792 | |||
| 2793 |
6/8✗ Branch 0 not taken.
✓ Branch 1 taken 11176492 times.
✓ Branch 2 taken 11008931 times.
✓ Branch 3 taken 167561 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 167561 times.
✓ Branch 6 taken 5145 times.
✓ Branch 7 taken 162416 times.
|
11176492 | if (WSREP(thd)) { |
| 2794 | /* wsrep BF abort in query exec phase */ | ||
| 2795 |
1/2✓ Branch 0 taken 162417 times.
✗ Branch 1 not taken.
|
162416 | mysql_mutex_lock(&thd->LOCK_wsrep_thd); |
| 2796 | 162417 | do_end_of_statement = | |
| 2797 |
3/4✓ Branch 0 taken 162417 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 162402 times.
|
324834 | !(thd->wsrep_trx().state() != wsrep::transaction::s_replaying && |
| 2798 | 162417 | !thd->killed); | |
| 2799 | |||
| 2800 |
1/2✓ Branch 0 taken 162259 times.
✗ Branch 1 not taken.
|
162417 | mysql_mutex_unlock(&thd->LOCK_wsrep_thd); |
| 2801 | } | ||
| 2802 | |||
| 2803 | #endif /* WITH_WSREP */ | ||
| 2804 | |||
| 2805 | 11014076 | done: | |
| 2806 |
3/4✓ Branch 0 taken 44703 times.
✓ Branch 1 taken 11131637 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 44703 times.
|
11176340 | assert(thd->open_tables == nullptr || |
| 2807 | (thd->locked_tables_mode == LTM_LOCK_TABLES)); | ||
| 2808 | |||
| 2809 | /* Update user statistics only if at least one timer was initialized */ | ||
| 2810 |
5/6✓ Branch 0 taken 11174549 times.
✓ Branch 1 taken 1791 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11174649 times.
✓ Branch 4 taken 1691 times.
✓ Branch 5 taken 11174649 times.
|
11176340 | if (unlikely(start_busy_usecs > 0.0 || start_cpu_nsecs > 0.0)) { |
| 2811 | 1691 | userstat_finish_timer(start_busy_usecs, start_cpu_nsecs, &thd->busy_time, | |
| 2812 | 1691 | &thd->cpu_time); | |
| 2813 | /* Updates THD stats and the global user stats. */ | ||
| 2814 | 1691 | thd->update_stats(true); | |
| 2815 |
1/2✓ Branch 0 taken 1691 times.
✗ Branch 1 not taken.
|
1691 | update_global_user_stats(thd, true, my_getsystime()); |
| 2816 | } | ||
| 2817 | |||
| 2818 | /* Finalize server status flags after executing a command. */ | ||
| 2819 |
1/2✓ Branch 0 taken 11177227 times.
✗ Branch 1 not taken.
|
11176340 | thd->update_slow_query_status(); |
| 2820 |
3/4✓ Branch 0 taken 6129 times.
✓ Branch 1 taken 11171111 times.
✓ Branch 2 taken 6128 times.
✗ Branch 3 not taken.
|
11177227 | if (thd->killed) thd->send_kill_message(); |
| 2821 |
1/2✓ Branch 0 taken 11176908 times.
✗ Branch 1 not taken.
|
11177239 | thd->send_statement_status(); |
| 2822 | |||
| 2823 | /* After sending response, switch to clone protocol */ | ||
| 2824 |
2/2✓ Branch 0 taken 2153 times.
✓ Branch 1 taken 11174755 times.
|
11176908 | if (clone_cmd != nullptr) { |
| 2825 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2153 times.
|
2153 | assert(command == COM_CLONE); |
| 2826 |
1/2✓ Branch 0 taken 2153 times.
✗ Branch 1 not taken.
|
2153 | error = clone_cmd->execute_server(thd); |
| 2827 | } | ||
| 2828 | |||
| 2829 |
4/4✓ Branch 0 taken 442 times.
✓ Branch 1 taken 11176466 times.
✓ Branch 2 taken 368 times.
✓ Branch 3 taken 74 times.
|
11176908 | if (command == COM_SUBSCRIBE_GROUP_REPLICATION_STREAM && !error) { |
| 2830 | 368 | call_gr_incoming_connection_cb( | |
| 2831 | 368 | thd, thd->active_vio->mysql_socket.fd, | |
| 2832 |
1/2✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
|
368 | thd->active_vio->ssl_arg ? static_cast<SSL *>(thd->active_vio->ssl_arg) |
| 2833 | : nullptr); | ||
| 2834 | } | ||
| 2835 | |||
| 2836 | #ifdef WITH_WSREP | ||
| 2837 |
2/2✓ Branch 0 taken 11014225 times.
✓ Branch 1 taken 162683 times.
|
11176908 | if (do_end_of_statement) { |
| 2838 | #endif /* WITH_WSREP */ | ||
| 2839 |
1/2✓ Branch 0 taken 11014816 times.
✗ Branch 1 not taken.
|
11014225 | thd->rpl_thd_ctx.session_gtids_ctx().notify_after_response_packet(thd); |
| 2840 | #ifdef WITH_WSREP | ||
| 2841 | } | ||
| 2842 | #endif /* WITH_WSREP */ | ||
| 2843 | |||
| 2844 |
7/8✓ Branch 0 taken 11177156 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11083693 times.
✓ Branch 3 taken 93463 times.
✓ Branch 4 taken 11082943 times.
✓ Branch 5 taken 616 times.
✓ Branch 6 taken 11082966 times.
✓ Branch 7 taken 94056 times.
|
11177499 | if (!thd->is_error() && !thd->killed) |
| 2845 |
1/2✓ Branch 0 taken 11082317 times.
✗ Branch 1 not taken.
|
11082966 | mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_RESULT), 0, nullptr, |
| 2846 | 0); | ||
| 2847 | |||
| 2848 |
1/2✓ Branch 0 taken 11176219 times.
✗ Branch 1 not taken.
|
11176373 | const std::string &cn = Command_names::str_global(command); |
| 2849 |
3/4✓ Branch 0 taken 93471 times.
✓ Branch 1 taken 11083281 times.
✓ Branch 2 taken 11177147 times.
✗ Branch 3 not taken.
|
22446442 | mysql_audit_notify( |
| 2850 | thd, AUDIT_EVENT(MYSQL_AUDIT_GENERAL_STATUS), | ||
| 2851 | 11270111 | thd->get_stmt_da()->is_error() ? thd->get_stmt_da()->mysql_errno() : 0, | |
| 2852 | cn.c_str(), cn.length()); | ||
| 2853 | |||
| 2854 | /* command_end is informational only. The plugin cannot abort | ||
| 2855 | execution of the command at this point. */ | ||
| 2856 |
1/2✓ Branch 0 taken 11176735 times.
✗ Branch 1 not taken.
|
11177147 | mysql_audit_notify(thd, AUDIT_EVENT(MYSQL_AUDIT_COMMAND_END), command, |
| 2857 | cn.c_str()); | ||
| 2858 | |||
| 2859 |
1/2✓ Branch 0 taken 11177020 times.
✗ Branch 1 not taken.
|
11176735 | log_slow_statement(thd); |
| 2860 | |||
| 2861 |
1/2✓ Branch 0 taken 11176396 times.
✗ Branch 1 not taken.
|
11177020 | THD_STAGE_INFO(thd, stage_cleaning_up); |
| 2862 |
2/2✓ Branch 0 taken 162406 times.
✓ Branch 1 taken 11013990 times.
|
11176396 | if (thd->lex->sql_command == SQLCOM_CREATE_TABLE) { |
| 2863 |
3/4✓ Branch 0 taken 162373 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 162373 times.
✗ Branch 3 not taken.
|
162406 | DEBUG_SYNC(thd, "dispatch_create_table_command_before_thd_root_free"); |
| 2864 | } | ||
| 2865 | |||
| 2866 |
2/2✓ Branch 0 taken 2872 times.
✓ Branch 1 taken 11173560 times.
|
11176396 | if (thd->killed == THD::KILL_QUERY) { |
| 2867 | 2872 | thd->killed = THD::NOT_KILLED; | |
| 2868 | } | ||
| 2869 | |||
| 2870 |
1/2✓ Branch 0 taken 11177362 times.
✗ Branch 1 not taken.
|
11176432 | thd->reset_query(); |
| 2871 |
1/2✓ Branch 0 taken 11176566 times.
✗ Branch 1 not taken.
|
11177362 | thd->set_command(COM_SLEEP); |
| 2872 | 11176566 | thd->set_proc_info(nullptr); | |
| 2873 | 11176743 | thd->lex->sql_command = SQLCOM_END; | |
| 2874 | |||
| 2875 | /* Performance Schema Interface instrumentation, end */ | ||
| 2876 |
1/2✓ Branch 0 taken 11175738 times.
✗ Branch 1 not taken.
|
11176743 | MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); |
| 2877 | 11175738 | thd->m_statement_psi = nullptr; | |
| 2878 | 11175738 | thd->m_digest = nullptr; | |
| 2879 |
1/2✓ Branch 0 taken 11177394 times.
✗ Branch 1 not taken.
|
11175738 | thd->reset_query_for_display(); |
| 2880 | |||
| 2881 | /* Prevent rewritten query from getting "stuck" in SHOW PROCESSLIST. */ | ||
| 2882 |
1/2✓ Branch 0 taken 11176848 times.
✗ Branch 1 not taken.
|
11177394 | thd->reset_rewritten_query(); |
| 2883 | |||
| 2884 | 11176848 | thd_manager->dec_thread_running(); | |
| 2885 | |||
| 2886 | /* Freeing the memroot will leave the THD::work_part_info invalid. */ | ||
| 2887 | 11177121 | thd->work_part_info = nullptr; | |
| 2888 | |||
| 2889 | /* | ||
| 2890 | If we've allocated a lot of memory (compared to the default preallocation | ||
| 2891 | size = 8192; note that we don't actually preallocate anymore), free | ||
| 2892 | it so that one big query won't cause us to hold on to a lot of RAM forever. | ||
| 2893 | If not, keep the last block so that the next query will hopefully be able to | ||
| 2894 | run without allocating memory from the OS. | ||
| 2895 | |||
| 2896 | The factor 5 is pretty much arbitrary, but ends up allowing three | ||
| 2897 | allocations (1 + 1.5 + 1.5²) under the current allocation policy. | ||
| 2898 | */ | ||
| 2899 | 11177121 | constexpr size_t kPreallocSz = 40960; | |
| 2900 |
2/2✓ Branch 0 taken 10523457 times.
✓ Branch 1 taken 652430 times.
|
11177121 | if (thd->mem_root->allocated_size() < kPreallocSz) |
| 2901 |
1/2✓ Branch 0 taken 10524559 times.
✗ Branch 1 not taken.
|
10523457 | thd->mem_root->ClearForReuse(); |
| 2902 | else | ||
| 2903 |
1/2✓ Branch 0 taken 652430 times.
✗ Branch 1 not taken.
|
652430 | thd->mem_root->Clear(); |
| 2904 | |||
| 2905 | /* SHOW PROFILE instrumentation, end */ | ||
| 2906 | #if defined(ENABLED_PROFILING) | ||
| 2907 |
1/2✓ Branch 0 taken 11177020 times.
✗ Branch 1 not taken.
|
11176989 | thd->profiling->finish_current_query(); |
| 2908 | #endif | ||
| 2909 | |||
| 2910 | 11176543 | return error; | |
| 2911 | 11177020 | } | |
| 2912 | |||
| 2913 | /** | ||
| 2914 | Shutdown the mysqld server. | ||
| 2915 | |||
| 2916 | @param thd Thread (session) context. | ||
| 2917 | @param level Shutdown level. | ||
| 2918 | |||
| 2919 | @retval | ||
| 2920 | true success | ||
| 2921 | @retval | ||
| 2922 | false When user has insufficient privilege or unsupported | ||
| 2923 | shutdown level | ||
| 2924 | |||
| 2925 | */ | ||
| 2926 | |||
| 2927 | 7781 | bool shutdown(THD *thd, enum mysql_enum_shutdown_level level) { | |
| 2928 |
1/2✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
|
7781 | DBUG_TRACE; |
| 2929 | 7781 | bool res = false; | |
| 2930 | 7781 | thd->lex->no_write_to_binlog = true; | |
| 2931 | |||
| 2932 |
2/4✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7781 times.
|
7781 | if (check_global_access(thd, SHUTDOWN_ACL)) |
| 2933 | ✗ | goto error; /* purecov: inspected */ | |
| 2934 | |||
| 2935 |
1/2✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
|
7781 | if (level == SHUTDOWN_DEFAULT) |
| 2936 | 7781 | level = SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable | |
| 2937 | ✗ | else if (level != SHUTDOWN_WAIT_ALL_BUFFERS) { | |
| 2938 | ✗ | my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level"); | |
| 2939 | ✗ | goto error; | |
| 2940 | ; | ||
| 2941 | } | ||
| 2942 | |||
| 2943 |
1/2✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
|
7781 | my_ok(thd); |
| 2944 | |||
| 2945 |
9/18✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7781 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7781 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7781 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7781 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7781 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 7781 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 7781 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 7781 times.
✗ Branch 17 not taken.
|
7781 | LogErr(SYSTEM_LEVEL, ER_SERVER_SHUTDOWN_INFO, |
| 2946 | thd->security_context()->user().str, server_version, | ||
| 2947 | MYSQL_COMPILATION_COMMENT_SERVER); | ||
| 2948 | |||
| 2949 |
5/8✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7781 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7780 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
7781 | DBUG_PRINT("quit", ("Got shutdown command for level %u", level)); |
| 2950 |
1/2✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
|
7781 | query_logger.general_log_print(thd, COM_QUERY, NullS); |
| 2951 |
1/2✓ Branch 0 taken 7781 times.
✗ Branch 1 not taken.
|
7781 | kill_mysql(); |
| 2952 | 7781 | res = true; | |
| 2953 | |||
| 2954 | 7781 | error: | |
| 2955 | 7781 | return res; | |
| 2956 | 7781 | } | |
| 2957 | |||
| 2958 | /** | ||
| 2959 | Create a TABLE_LIST object for an INFORMATION_SCHEMA table. | ||
| 2960 | |||
| 2961 | This function is used in the parser to convert a SHOW or DESCRIBE | ||
| 2962 | table_name command to a SELECT from INFORMATION_SCHEMA. | ||
| 2963 | It prepares a Query_block and a TABLE_LIST object to represent the | ||
| 2964 | given command as a SELECT parse tree. | ||
| 2965 | |||
| 2966 | @param thd thread handle | ||
| 2967 | @param lex current lex | ||
| 2968 | @param table_ident table alias if it's used | ||
| 2969 | @param schema_table_idx the type of the INFORMATION_SCHEMA table to be | ||
| 2970 | created | ||
| 2971 | |||
| 2972 | @note | ||
| 2973 | Due to the way this function works with memory and LEX it cannot | ||
| 2974 | be used outside the parser (parse tree transformations outside | ||
| 2975 | the parser break PS and SP). | ||
| 2976 | |||
| 2977 | @retval | ||
| 2978 | 0 success | ||
| 2979 | @retval | ||
| 2980 | 1 out of memory or SHOW commands are not allowed | ||
| 2981 | in this version of the server. | ||
| 2982 | */ | ||
| 2983 | |||
| 2984 | 362 | int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, | |
| 2985 | enum enum_schema_tables schema_table_idx) { | ||
| 2986 | 362 | Query_block *schema_query_block = nullptr; | |
| 2987 |
1/2✓ Branch 0 taken 362 times.
✗ Branch 1 not taken.
|
362 | DBUG_TRACE; |
| 2988 | |||
| 2989 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 330 times.
|
362 | switch (schema_table_idx) { |
| 2990 | ✗ | case SCH_TMP_TABLE_COLUMNS: | |
| 2991 | case SCH_TMP_TABLE_KEYS: { | ||
| 2992 | ✗ | assert(table_ident); | |
| 2993 | ✗ | TABLE_LIST **query_tables_last = lex->query_tables_last; | |
| 2994 | ✗ | if ((schema_query_block = lex->new_empty_query_block()) == nullptr) | |
| 2995 | ✗ | return 1; /* purecov: inspected */ | |
| 2996 | ✗ | if (!schema_query_block->add_table_to_list(thd, table_ident, nullptr, 0, | |
| 2997 | TL_READ, MDL_SHARED_READ)) | ||
| 2998 | ✗ | return 1; | |
| 2999 | ✗ | lex->query_tables_last = query_tables_last; | |
| 3000 | ✗ | break; | |
| 3001 | } | ||
| 3002 | 26 | case SCH_PROFILES: | |
| 3003 | /* | ||
| 3004 | Mark this current profiling record to be discarded. We don't | ||
| 3005 | wish to have SHOW commands show up in profiling-> | ||
| 3006 | */ | ||
| 3007 | #if defined(ENABLED_PROFILING) | ||
| 3008 |
1/2✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
|
26 | thd->profiling->discard_current_query(); |
| 3009 | #endif | ||
| 3010 | 26 | break; | |
| 3011 | 6 | case SCH_USER_STATS: | |
| 3012 | case SCH_CLIENT_STATS: | ||
| 3013 | case SCH_THREAD_STATS: | ||
| 3014 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
6 | if (check_global_access(thd, SUPER_ACL | PROCESS_ACL)) return 1; |
| 3015 | case SCH_TABLE_STATS: | ||
| 3016 | case SCH_INDEX_STATS: | ||
| 3017 | case SCH_OPTIMIZER_TRACE: | ||
| 3018 | case SCH_OPEN_TABLES: | ||
| 3019 | case SCH_ENGINES: | ||
| 3020 | case SCH_USER_PRIVILEGES: | ||
| 3021 | case SCH_SCHEMA_PRIVILEGES: | ||
| 3022 | case SCH_TABLE_PRIVILEGES: | ||
| 3023 | case SCH_COLUMN_PRIVILEGES: | ||
| 3024 | case SCH_TEMPORARY_TABLES: | ||
| 3025 | case SCH_GLOBAL_TEMPORARY_TABLES: | ||
| 3026 | default: | ||
| 3027 | 336 | break; | |
| 3028 | } | ||
| 3029 | |||
| 3030 | 362 | Query_block *query_block = lex->current_query_block(); | |
| 3031 |
2/4✓ Branch 0 taken 362 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 362 times.
|
362 | if (make_schema_query_block(thd, query_block, schema_table_idx)) { |
| 3032 | ✗ | return 1; | |
| 3033 | } | ||
| 3034 | 362 | TABLE_LIST *table_list = query_block->table_list.first; | |
| 3035 | 362 | table_list->schema_query_block = schema_query_block; | |
| 3036 | 362 | table_list->schema_table_reformed = true; | |
| 3037 | 362 | return 0; | |
| 3038 | 362 | } | |
| 3039 | |||
| 3040 | /** | ||
| 3041 | Read query from packet and store in thd->query. | ||
| 3042 | Used in COM_QUERY and COM_STMT_PREPARE. | ||
| 3043 | |||
| 3044 | Sets the following THD variables: | ||
| 3045 | - query | ||
| 3046 | - query_length | ||
| 3047 | |||
| 3048 | @retval | ||
| 3049 | false ok | ||
| 3050 | @retval | ||
| 3051 | true error; In this case thd->fatal_error is set | ||
| 3052 | */ | ||
| 3053 | |||
| 3054 | 19023938 | bool alloc_query(THD *thd, const char *packet, size_t packet_length) { | |
| 3055 | /* Remove garbage at start and end of query */ | ||
| 3056 |
5/6✓ Branch 0 taken 19041084 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16887 times.
✓ Branch 3 taken 19024406 times.
✓ Branch 4 taken 16887 times.
✓ Branch 5 taken 19024147 times.
|
19040825 | while (packet_length > 0 && my_isspace(thd->charset(), packet[0])) { |
| 3057 | 16887 | packet++; | |
| 3058 | 16887 | packet_length--; | |
| 3059 | } | ||
| 3060 | 19024147 | const char *pos = packet + packet_length; // Point at end null | |
| 3061 |
3/4✓ Branch 0 taken 23909040 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4884327 times.
✓ Branch 3 taken 19024206 times.
|
47817573 | while (packet_length > 0 && |
| 3062 |
4/4✓ Branch 0 taken 21744095 times.
✓ Branch 1 taken 2164945 times.
✓ Branch 2 taken 2719383 times.
✓ Branch 3 taken 19024771 times.
|
23909040 | (pos[-1] == ';' || my_isspace(thd->charset(), pos[-1]))) { |
| 3063 | 4884327 | pos--; | |
| 3064 | 4884327 | packet_length--; | |
| 3065 | } | ||
| 3066 | |||
| 3067 | 19024206 | char *query = static_cast<char *>(thd->alloc(packet_length + 1)); | |
| 3068 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19024594 times.
|
19024594 | if (!query) return true; |
| 3069 | 19024594 | memcpy(query, packet, packet_length); | |
| 3070 | 19024594 | query[packet_length] = '\0'; | |
| 3071 | |||
| 3072 | 19024594 | thd->set_query(query, packet_length); | |
| 3073 | |||
| 3074 | 19025694 | return false; | |
| 3075 | } | ||
| 3076 | |||
| 3077 | 37130 | static bool sp_process_definer(THD *thd) { | |
| 3078 |
1/2✓ Branch 0 taken 37130 times.
✗ Branch 1 not taken.
|
37130 | DBUG_TRACE; |
| 3079 | |||
| 3080 | 37130 | LEX *lex = thd->lex; | |
| 3081 | |||
| 3082 | /* | ||
| 3083 | If the definer is not specified, this means that CREATE-statement missed | ||
| 3084 | DEFINER-clause. DEFINER-clause can be missed in two cases: | ||
| 3085 | |||
| 3086 | - The user submitted a statement w/o the clause. This is a normal | ||
| 3087 | case, we should assign CURRENT_USER as definer. | ||
| 3088 | |||
| 3089 | - Our slave received an updated from the master, that does not | ||
| 3090 | replicate definer for stored routines. We should also assign | ||
| 3091 | CURRENT_USER as definer here, but also we should mark this routine | ||
| 3092 | as NON-SUID. This is essential for the sake of backward | ||
| 3093 | compatibility. | ||
| 3094 | |||
| 3095 | The problem is the slave thread is running under "special" user (@), | ||
| 3096 | that actually does not exist. In the older versions we do not fail | ||
| 3097 | execution of a stored routine if its definer does not exist and | ||
| 3098 | continue the execution under the authorization of the invoker | ||
| 3099 | (BUG#13198). And now if we try to switch to slave-current-user (@), | ||
| 3100 | we will fail. | ||
| 3101 | |||
| 3102 | Actually, this leads to the inconsistent state of master and | ||
| 3103 | slave (different definers, different SUID behaviour), but it seems, | ||
| 3104 | this is the best we can do. | ||
| 3105 | */ | ||
| 3106 | |||
| 3107 |
2/2✓ Branch 0 taken 15973 times.
✓ Branch 1 taken 21157 times.
|
37130 | if (!lex->definer) { |
| 3108 |
1/2✓ Branch 0 taken 15973 times.
✗ Branch 1 not taken.
|
15973 | Prepared_stmt_arena_holder ps_arena_holder(thd); |
| 3109 | |||
| 3110 |
1/2✓ Branch 0 taken 15973 times.
✗ Branch 1 not taken.
|
15973 | lex->definer = create_default_definer(thd); |
| 3111 | |||
| 3112 | /* Error has been already reported. */ | ||
| 3113 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15973 times.
|
15973 | if (lex->definer == nullptr) return true; |
| 3114 | |||
| 3115 |
4/4✓ Branch 0 taken 50 times.
✓ Branch 1 taken 15923 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 42 times.
|
15973 | if (thd->slave_thread && lex->sphead) |
| 3116 | 8 | lex->sphead->m_chistics->suid = SP_IS_NOT_SUID; | |
| 3117 |
1/2✓ Branch 0 taken 15973 times.
✗ Branch 1 not taken.
|
15973 | } else { |
| 3118 | /* | ||
| 3119 | If the specified definer differs from the current user, we | ||
| 3120 | should check that the current user has a set_user_id privilege | ||
| 3121 | (in order to create a stored routine under another user one must | ||
| 3122 | have a set_user_id privilege). | ||
| 3123 | */ | ||
| 3124 | 21157 | Security_context *sctx = thd->security_context(); | |
| 3125 | 42314 | if ((strcmp(lex->definer->user.str, | |
| 3126 |
5/6✓ Branch 0 taken 21157 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
✓ Branch 3 taken 20999 times.
✓ Branch 4 taken 20999 times.
✓ Branch 5 taken 158 times.
|
21315 | thd->security_context()->priv_user().str) || |
| 3127 |
3/6✓ Branch 0 taken 158 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 158 times.
|
158 | my_strcasecmp(system_charset_info, lex->definer->host.str, |
| 3128 | thd->security_context()->priv_host().str))) { | ||
| 3129 |
8/16✓ Branch 0 taken 20999 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20999 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 20984 times.
✓ Branch 6 taken 20999 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20999 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 20995 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
21014 | if (!(sctx->check_access(SUPER_ACL) || |
| 3130 |
3/4✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11 times.
|
15 | sctx->has_global_grant(STRING_WITH_LEN("SET_USER_ID")).first)) { |
| 3131 | 4 | thd->diff_access_denied_errors++; | |
| 3132 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), |
| 3133 | "SUPER or SET_USER_ID"); | ||
| 3134 | 4 | return true; | |
| 3135 | } | ||
| 3136 |
4/6✓ Branch 0 taken 20995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20995 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 20991 times.
|
20995 | if (sctx->can_operate_with({lex->definer}, consts::system_user)) |
| 3137 | 4 | return true; | |
| 3138 | } | ||
| 3139 | } | ||
| 3140 | |||
| 3141 | /* Check that the specified definer exists. Emit a warning if not. */ | ||
| 3142 | |||
| 3143 |
3/4✓ Branch 0 taken 37122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9524 times.
✓ Branch 3 taken 27598 times.
|
37122 | if (!is_acl_user(thd, lex->definer->host.str, lex->definer->user.str)) { |
| 3144 |
1/2✓ Branch 0 taken 9524 times.
✗ Branch 1 not taken.
|
9524 | push_warning_printf(thd, Sql_condition::SL_NOTE, ER_NO_SUCH_USER, |
| 3145 | 9524 | ER_THD(thd, ER_NO_SUCH_USER), lex->definer->user.str, | |
| 3146 |
1/2✓ Branch 0 taken 9524 times.
✗ Branch 1 not taken.
|
9524 | lex->definer->host.str); |
| 3147 | } | ||
| 3148 | |||
| 3149 | 37122 | return false; | |
| 3150 | 37130 | } | |
| 3151 | |||
| 3152 | /** | ||
| 3153 | Auxiliary call that opens and locks tables for LOCK TABLES statement | ||
| 3154 | and initializes the list of locked tables. | ||
| 3155 | |||
| 3156 | @param thd Thread context. | ||
| 3157 | @param tables List of tables to be locked. | ||
| 3158 | |||
| 3159 | @return false in case of success, true in case of error. | ||
| 3160 | */ | ||
| 3161 | |||
| 3162 | 2619 | static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables) { | |
| 3163 | 2619 | Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; | |
| 3164 | 2619 | MDL_deadlock_and_lock_abort_error_handler deadlock_handler; | |
| 3165 |
1/2✓ Branch 0 taken 2619 times.
✗ Branch 1 not taken.
|
2619 | MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint(); |
| 3166 | uint counter; | ||
| 3167 | TABLE_LIST *table; | ||
| 3168 | |||
| 3169 | 2619 | thd->in_lock_tables = true; | |
| 3170 | |||
| 3171 | 2620 | retry: | |
| 3172 | |||
| 3173 |
3/4✓ Branch 0 taken 2620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 2579 times.
|
2620 | if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy)) |
| 3174 | 41 | goto err; | |
| 3175 | |||
| 3176 | 2579 | deadlock_handler.init(); | |
| 3177 |
1/2✓ Branch 0 taken 2579 times.
✗ Branch 1 not taken.
|
2579 | thd->push_internal_handler(&deadlock_handler); |
| 3178 | |||
| 3179 |
2/2✓ Branch 0 taken 11905 times.
✓ Branch 1 taken 2578 times.
|
14483 | for (table = tables; table; table = table->next_global) { |
| 3180 |
2/2✓ Branch 0 taken 8564 times.
✓ Branch 1 taken 3341 times.
|
11905 | if (!table->is_placeholder()) { |
| 3181 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 8538 times.
|
8564 | if (table->table->s->tmp_table) { |
| 3182 | /* | ||
| 3183 | We allow to change temporary tables even if they were locked for read | ||
| 3184 | by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK | ||
| 3185 | TABLES time and by the statement which is later executed under LOCK | ||
| 3186 | TABLES we ensure that for temporary tables we always request a write | ||
| 3187 | lock (such discrepancy can cause problems for the storage engine). | ||
| 3188 | We don't set TABLE_LIST::lock_type in this case as this might result | ||
| 3189 | in extra warnings from THD::decide_logging_format() even though | ||
| 3190 | binary logging is totally irrelevant for LOCK TABLES. | ||
| 3191 | */ | ||
| 3192 | 26 | table->table->reginfo.lock_type = TL_WRITE; | |
| 3193 | 8538 | } else if (table->lock_descriptor().type == TL_READ && | |
| 3194 |
5/6✓ Branch 0 taken 1424 times.
✓ Branch 1 taken 7114 times.
✓ Branch 2 taken 1424 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1135 times.
✓ Branch 5 taken 7403 times.
|
9962 | !table->prelocking_placeholder && |
| 3195 |
2/2✓ Branch 0 taken 1135 times.
✓ Branch 1 taken 289 times.
|
1424 | table->table->file->ha_table_flags() & HA_NO_READ_LOCAL_LOCK) { |
| 3196 | /* | ||
| 3197 | In case when LOCK TABLE ... READ LOCAL was issued for table with | ||
| 3198 | storage engine which doesn't support READ LOCAL option and doesn't | ||
| 3199 | use THR_LOCK locks we need to upgrade weak SR metadata lock acquired | ||
| 3200 | in open_tables() to stronger SRO metadata lock. | ||
| 3201 | This is not needed for tables used through stored routines or | ||
| 3202 | triggers as we always acquire SRO (or even stronger SNRW) metadata | ||
| 3203 | lock for them. | ||
| 3204 | */ | ||
| 3205 | 2270 | bool result = thd->mdl_context.upgrade_shared_lock( | |
| 3206 |
1/2✓ Branch 0 taken 1135 times.
✗ Branch 1 not taken.
|
1135 | table->table->mdl_ticket, MDL_SHARED_READ_ONLY, |
| 3207 | thd->variables.lock_wait_timeout); | ||
| 3208 | |||
| 3209 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1134 times.
|
1135 | if (deadlock_handler.need_reopen()) { |
| 3210 | /* | ||
| 3211 | Deadlock occurred during upgrade of metadata lock. | ||
| 3212 | Let us restart acquiring and opening tables for LOCK TABLES. | ||
| 3213 | */ | ||
| 3214 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | thd->pop_internal_handler(); |
| 3215 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | close_tables_for_reopen(thd, &tables, mdl_savepoint); |
| 3216 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (open_temporary_tables(thd, tables)) goto err; |
| 3217 | 1 | goto retry; | |
| 3218 | } | ||
| 3219 | |||
| 3220 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1134 times.
|
1134 | if (result) { |
| 3221 | ✗ | thd->pop_internal_handler(); | |
| 3222 | ✗ | goto err; | |
| 3223 | } | ||
| 3224 | } | ||
| 3225 | } | ||
| 3226 | } | ||
| 3227 | |||
| 3228 |
1/2✓ Branch 0 taken 2578 times.
✗ Branch 1 not taken.
|
2578 | thd->pop_internal_handler(); |
| 3229 | |||
| 3230 |
5/6✓ Branch 0 taken 2578 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2564 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 2564 times.
|
5142 | if (lock_tables(thd, tables, counter, 0) || |
| 3231 |
2/4✓ Branch 0 taken 2564 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2564 times.
|
2564 | thd->locked_tables_list.init_locked_tables(thd)) |
| 3232 | 14 | goto err; | |
| 3233 | |||
| 3234 | 2564 | thd->in_lock_tables = false; | |
| 3235 | |||
| 3236 | 2564 | return false; | |
| 3237 | |||
| 3238 | 55 | err: | |
| 3239 | 55 | thd->in_lock_tables = false; | |
| 3240 | |||
| 3241 |
1/2✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
|
55 | trans_rollback_stmt(thd); |
| 3242 | /* | ||
| 3243 | Need to end the current transaction, so the storage engine (InnoDB) | ||
| 3244 | can free its locks if LOCK TABLES locked some tables before finding | ||
| 3245 | that it can't lock a table in its list | ||
| 3246 | */ | ||
| 3247 |
1/2✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
|
55 | trans_rollback(thd); |
| 3248 | /* Close tables and release metadata locks. */ | ||
| 3249 |
1/2✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
|
55 | close_thread_tables(thd); |
| 3250 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
|
55 | assert(!thd->locked_tables_mode); |
| 3251 |
1/2✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
|
55 | thd->mdl_context.release_transactional_locks(); |
| 3252 | 55 | return true; | |
| 3253 | 2619 | } | |
| 3254 | |||
| 3255 | #ifdef WITH_WSREP | ||
| 3256 | 353 | static bool wsrep_is_show_query(enum enum_sql_command command) { | |
| 3257 |
2/4✓ Branch 0 taken 353 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 353 times.
✗ Branch 3 not taken.
|
353 | assert(command >= 0 && command <= SQLCOM_END); |
| 3258 | 353 | return (sql_command_flags[command] & CF_STATUS_COMMAND) != 0; | |
| 3259 | } | ||
| 3260 | #endif /* WITH_WSREP */ | ||
| 3261 | |||
| 3262 | /** | ||
| 3263 | Acquire a global backup lock. | ||
| 3264 | |||
| 3265 | @param thd Thread context. | ||
| 3266 | |||
| 3267 | @return false on success, true in case of error. | ||
| 3268 | */ | ||
| 3269 | |||
| 3270 | 254 | static bool lock_tables_for_backup(THD *thd) { | |
| 3271 |
1/2✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
|
254 | DBUG_TRACE; |
| 3272 | |||
| 3273 |
2/4✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 254 times.
|
254 | if (check_backup_admin_privilege(thd)) return true; |
| 3274 | |||
| 3275 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 254 times.
|
254 | if (delay_key_write_options == DELAY_KEY_WRITE_ALL) { |
| 3276 | ✗ | my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "delay_key_write=ALL"); | |
| 3277 | ✗ | return true; | |
| 3278 | } | ||
| 3279 | /* | ||
| 3280 | Do nothing if the current connection already owns the LOCK TABLES FOR | ||
| 3281 | BACKUP lock or the global read lock (as it's a more restrictive lock). | ||
| 3282 | */ | ||
| 3283 |
3/6✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 254 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 254 times.
|
508 | if (thd->backup_tables_lock.is_acquired() || |
| 3284 | 254 | thd->global_read_lock.is_acquired()) | |
| 3285 | ✗ | return false; | |
| 3286 | |||
| 3287 | /* | ||
| 3288 | Do not allow backup locks under regular LOCK TABLES, FLUSH TABLES ... FOR | ||
| 3289 | EXPORT, or FLUSH TABLES <table_list> WITH READ LOCK. | ||
| 3290 | */ | ||
| 3291 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 254 times.
|
254 | if (thd->variables.option_bits & OPTION_TABLE_LOCK) { |
| 3292 | ✗ | my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); | |
| 3293 | ✗ | return true; | |
| 3294 | } | ||
| 3295 | |||
| 3296 |
1/2✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
|
254 | bool res = thd->backup_tables_lock.acquire(thd); |
| 3297 | |||
| 3298 |
2/4✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 254 times.
|
254 | if (ha_store_binlog_info(thd)) { |
| 3299 | ✗ | thd->backup_tables_lock.release(thd); | |
| 3300 | ✗ | res = true; | |
| 3301 | } | ||
| 3302 | |||
| 3303 | 254 | return res; | |
| 3304 | 254 | } | |
| 3305 | |||
| 3306 | /** | ||
| 3307 | This is a wrapper for MYSQL_BIN_LOG::gtid_end_transaction. For normal | ||
| 3308 | statements, the function gtid_end_transaction is called in the commit | ||
| 3309 | handler. However, if the statement is filtered out or not written to | ||
| 3310 | the binary log, the commit handler is not invoked. Therefore, this | ||
| 3311 | wrapper calls gtid_end_transaction in case the current statement is | ||
| 3312 | committing but was not written to the binary log. | ||
| 3313 | (The function gtid_end_transaction ensures that gtid-related | ||
| 3314 | end-of-transaction operations are performed; this includes | ||
| 3315 | generating an empty transaction and calling | ||
| 3316 | Gtid_state::update_gtids_impl.) | ||
| 3317 | |||
| 3318 | @param thd Thread (session) context. | ||
| 3319 | */ | ||
| 3320 | |||
| 3321 | 21224920 | static inline void binlog_gtid_end_transaction(THD *thd) { | |
| 3322 |
1/2✓ Branch 0 taken 21226081 times.
✗ Branch 1 not taken.
|
21224920 | DBUG_TRACE; |
| 3323 | |||
| 3324 | /* | ||
| 3325 | This performs end-of-transaction actions needed by GTIDs: | ||
| 3326 | in particular, it generates an empty transaction if | ||
| 3327 | needed (e.g., if the statement was filtered out). | ||
| 3328 | |||
| 3329 | It is executed at the end of an implicitly or explicitly | ||
| 3330 | committing statement. | ||
| 3331 | |||
| 3332 | In addition, it is executed after CREATE TEMPORARY TABLE | ||
| 3333 | or DROP TEMPORARY TABLE when they occur outside | ||
| 3334 | transactional context. When enforce_gtid_consistency is | ||
| 3335 | enabled, these statements cannot occur in transactional | ||
| 3336 | context, and then they behave exactly as implicitly | ||
| 3337 | committing: they are written to the binary log | ||
| 3338 | immediately, not wrapped in BEGIN/COMMIT, and cannot be | ||
| 3339 | rolled back. However, they do not count as implicitly | ||
| 3340 | committing according to stmt_causes_implicit_commit(), so | ||
| 3341 | we need to add special cases in the condition below. Hence | ||
| 3342 | the clauses for SQLCOM_CREATE_TABLE and SQLCOM_DROP_TABLE. | ||
| 3343 | |||
| 3344 | If enforce_gtid_consistency=off, CREATE TEMPORARY TABLE | ||
| 3345 | and DROP TEMPORARY TABLE can occur in the middle of a | ||
| 3346 | transaction. Then they do not behave as DDL; they are | ||
| 3347 | written to the binary log inside BEGIN/COMMIT. | ||
| 3348 | |||
| 3349 | (For base tables, SQLCOM_[CREATE|DROP]_TABLE match both | ||
| 3350 | the stmt_causes_implicit_commit(...) clause and the | ||
| 3351 | thd->lex->sql_command == SQLCOM_* clause; for temporary | ||
| 3352 | tables they match only thd->lex->sql_command == SQLCOM_*.) | ||
| 3353 | */ | ||
| 3354 | 63404454 | if (thd->lex->sql_command == SQLCOM_COMMIT || | |
| 3355 |
2/2✓ Branch 0 taken 20951828 times.
✓ Branch 1 taken 390 times.
|
20952218 | thd->lex->sql_command == SQLCOM_XA_PREPARE || |
| 3356 |
2/2✓ Branch 0 taken 20951274 times.
✓ Branch 1 taken 554 times.
|
20951828 | thd->lex->sql_command == SQLCOM_XA_COMMIT || |
| 3357 |
2/2✓ Branch 0 taken 20951054 times.
✓ Branch 1 taken 220 times.
|
20951274 | thd->lex->sql_command == SQLCOM_XA_ROLLBACK || |
| 3358 |
7/8✓ Branch 0 taken 20952218 times.
✓ Branch 1 taken 273863 times.
✓ Branch 2 taken 20951178 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19752090 times.
✓ Branch 5 taken 1199088 times.
✓ Branch 6 taken 1526263 times.
✓ Branch 7 taken 19699892 times.
|
61930339 | stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END) || |
| 3359 |
2/2✓ Branch 0 taken 19689511 times.
✓ Branch 1 taken 62579 times.
|
19752090 | ((thd->lex->sql_command == SQLCOM_CREATE_TABLE || |
| 3360 |
2/2✓ Branch 0 taken 7230 times.
✓ Branch 1 taken 19682281 times.
|
19689511 | thd->lex->sql_command == SQLCOM_DROP_TABLE) && |
| 3361 |
2/2✓ Branch 0 taken 52149 times.
✓ Branch 1 taken 17610 times.
|
69809 | !thd->in_multi_stmt_transaction_mode())) |
| 3362 |
1/2✓ Branch 0 taken 1526330 times.
✗ Branch 1 not taken.
|
1526263 | (void)mysql_bin_log.gtid_end_transaction(thd); |
| 3363 | 21226222 | } | |
| 3364 | |||
| 3365 | /** | ||
| 3366 | Execute command saved in thd and lex->sql_command. | ||
| 3367 | |||
| 3368 | @param thd Thread handle | ||
| 3369 | @param first_level whether invocation of the | ||
| 3370 | mysql_execute_command() is a top level query or sub query. At the highest | ||
| 3371 | level, first_level value is true. Stored procedures can execute sub queries. | ||
| 3372 | In such cases first_level (recursive mysql_execute_command() call) will be | ||
| 3373 | false. | ||
| 3374 | |||
| 3375 | @todo this is workaround. right way will be move invalidating in | ||
| 3376 | the unlock procedure. | ||
| 3377 | @todo use check_change_password() | ||
| 3378 | |||
| 3379 | @retval false OK | ||
| 3380 | @retval true Error | ||
| 3381 | */ | ||
| 3382 | |||
| 3383 | 21389953 | int mysql_execute_command(THD *thd, bool first_level) { | |
| 3384 | 21389953 | int res = false; | |
| 3385 | 21389953 | LEX *const lex = thd->lex; | |
| 3386 | /* first Query_block (have special meaning for many of non-SELECTcommands) */ | ||
| 3387 | 21389953 | Query_block *const query_block = lex->query_block; | |
| 3388 | /* first table of first Query_block */ | ||
| 3389 | 21389953 | TABLE_LIST *const first_table = query_block->get_table_list(); | |
| 3390 | /* list of all tables in query */ | ||
| 3391 | TABLE_LIST *all_tables; | ||
| 3392 | // keep GTID violation state in order to roll it back on statement failure | ||
| 3393 | 21390468 | bool gtid_consistency_violation_state = thd->has_gtid_consistency_violation; | |
| 3394 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21390677 times.
|
21390468 | assert(query_block->master_query_expression() == lex->unit); |
| 3395 |
1/2✓ Branch 0 taken 21391437 times.
✗ Branch 1 not taken.
|
21390677 | DBUG_TRACE; |
| 3396 | /* EXPLAIN OTHER isn't explainable command, but can have describe flag. */ | ||
| 3397 |
6/8✓ Branch 0 taken 29254 times.
✓ Branch 1 taken 21362147 times.
✓ Branch 2 taken 29254 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 168 times.
✓ Branch 5 taken 29086 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 168 times.
|
21391437 | assert(!lex->is_explain() || is_explainable_query(lex->sql_command) || |
| 3398 | lex->sql_command == SQLCOM_EXPLAIN_OTHER); | ||
| 3399 | |||
| 3400 |
3/4✓ Branch 0 taken 27 times.
✓ Branch 1 taken 21391314 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
|
21391401 | assert(!thd->m_transactional_ddl.inited() || |
| 3401 | thd->in_active_multi_stmt_transaction()); | ||
| 3402 | |||
| 3403 | 21391341 | bool early_error_on_rep_command{false}; | |
| 3404 | |||
| 3405 |
2/4✓ Branch 0 taken 21391151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21391414 times.
✗ Branch 3 not taken.
|
21391341 | CONDITIONAL_SYNC_POINT_FOR_TIMESTAMP("before_execute_command"); |
| 3406 | |||
| 3407 | /* | ||
| 3408 | If there is a CREATE TABLE...START TRANSACTION command which | ||
| 3409 | is not yet committed or rollbacked, then we should allow only | ||
| 3410 | BINLOG INSERT, COMMIT or ROLLBACK command. | ||
| 3411 | TODO: Should we really check name of table when we cable BINLOG INSERT ? | ||
| 3412 | */ | ||
| 3413 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 13 times.
|
21391675 | if (thd->m_transactional_ddl.inited() && lex->sql_command != SQLCOM_COMMIT && |
| 3414 |
6/6✓ Branch 0 taken 27 times.
✓ Branch 1 taken 21391349 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 21391372 times.
|
21391414 | lex->sql_command != SQLCOM_ROLLBACK && |
| 3415 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
|
11 | lex->sql_command != SQLCOM_BINLOG_BASE64_EVENT) { |
| 3416 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | my_error(ER_STATEMENT_NOT_ALLOWED_AFTER_START_TRANSACTION, MYF(0)); |
| 3417 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | binlog_gtid_end_transaction(thd); |
| 3418 | 4 | return 1; | |
| 3419 | } | ||
| 3420 | |||
| 3421 | 21391372 | thd->work_part_info = nullptr; | |
| 3422 | |||
| 3423 |
2/2✓ Branch 0 taken 2026 times.
✓ Branch 1 taken 21388924 times.
|
21391372 | if (thd->optimizer_switch_flag(OPTIMIZER_SWITCH_SUBQUERY_TO_DERIVED)) |
| 3424 | 2026 | lex->add_statement_options(OPTION_NO_CONST_TABLES); | |
| 3425 | |||
| 3426 | /* | ||
| 3427 | Each statement or replication event which might produce deadlock | ||
| 3428 | should handle transaction rollback on its own. So by the start of | ||
| 3429 | the next statement transaction rollback request should be fulfilled | ||
| 3430 | already. | ||
| 3431 | */ | ||
| 3432 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 21390950 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
21390950 | assert(!thd->transaction_rollback_request || thd->in_sub_stmt); |
| 3433 | /* | ||
| 3434 | In many cases first table of main Query_block have special meaning => | ||
| 3435 | check that it is first table in global list and relink it first in | ||
| 3436 | queries_tables list if it is necessary (we need such relinking only | ||
| 3437 | for queries with subqueries in select list, in this case tables of | ||
| 3438 | subqueries will go to global list first) | ||
| 3439 | |||
| 3440 | all_tables will differ from first_table only if most upper Query_block | ||
| 3441 | do not contain tables. | ||
| 3442 | |||
| 3443 | Because of above in place where should be at least one table in most | ||
| 3444 | outer Query_block we have following check: | ||
| 3445 | assert(first_table == all_tables); | ||
| 3446 | assert(first_table == all_tables && first_table != 0); | ||
| 3447 | */ | ||
| 3448 |
1/2✓ Branch 0 taken 21391189 times.
✗ Branch 1 not taken.
|
21390950 | lex->first_lists_tables_same(); |
| 3449 | /* should be assigned after making first tables same */ | ||
| 3450 | 21391189 | all_tables = lex->query_tables; | |
| 3451 | /* set context for commands which do not use setup_tables */ | ||
| 3452 | 21391189 | query_block->context.resolve_in_table_list_only( | |
| 3453 | query_block->get_table_list()); | ||
| 3454 | |||
| 3455 |
1/2✓ Branch 0 taken 21391548 times.
✗ Branch 1 not taken.
|
21389700 | thd->get_stmt_da()->reset_diagnostics_area(); |
| 3456 |
2/2✓ Branch 0 taken 20738245 times.
✓ Branch 1 taken 653303 times.
|
21391548 | if ((thd->lex->keep_diagnostics != DA_KEEP_PARSE_ERROR) && |
| 3457 |
2/2✓ Branch 0 taken 20626008 times.
✓ Branch 1 taken 112237 times.
|
20738245 | (thd->lex->keep_diagnostics != DA_KEEP_DIAGNOSTICS)) { |
| 3458 | /* | ||
| 3459 | No parse errors, and it's not a diagnostic statement: | ||
| 3460 | remove the sql conditions from the DA! | ||
| 3461 | For diagnostic statements we need to keep the conditions | ||
| 3462 | around so we can inspec them. | ||
| 3463 | */ | ||
| 3464 |
1/2✓ Branch 0 taken 20625777 times.
✗ Branch 1 not taken.
|
20626008 | thd->get_stmt_da()->reset_condition_info(thd); |
| 3465 | } | ||
| 3466 | |||
| 3467 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 21391133 times.
|
21391317 | if (thd->resource_group_ctx()->m_warn != 0) { |
| 3468 | 4 | auto res_grp_name = thd->resource_group_ctx()->m_switch_resource_group_str; | |
| 3469 |
2/6✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
4 | switch (thd->resource_group_ctx()->m_warn) { |
| 3470 | ✗ | case WARN_RESOURCE_GROUP_UNSUPPORTED: { | |
| 3471 | ✗ | auto res_grp_mgr = resourcegroups::Resource_group_mgr::instance(); | |
| 3472 | ✗ | push_warning_printf(thd, Sql_condition::SL_WARNING, | |
| 3473 | ER_FEATURE_UNSUPPORTED, | ||
| 3474 | ER_THD(thd, ER_FEATURE_UNSUPPORTED), | ||
| 3475 | "Resource groups", res_grp_mgr->unsupport_reason()); | ||
| 3476 | ✗ | break; | |
| 3477 | } | ||
| 3478 | ✗ | case WARN_RESOURCE_GROUP_UNSUPPORTED_HINT: | |
| 3479 | ✗ | push_warning_printf(thd, Sql_condition::SL_WARNING, | |
| 3480 | ER_WARN_UNSUPPORTED_HINT, | ||
| 3481 | ER_THD(thd, ER_WARN_UNSUPPORTED_HINT), | ||
| 3482 | "Subquery or Stored procedure or Trigger"); | ||
| 3483 | ✗ | break; | |
| 3484 | 3 | case WARN_RESOURCE_GROUP_TYPE_MISMATCH: { | |
| 3485 | 3 | ulonglong pfs_thread_id = 0; | |
| 3486 | /* | ||
| 3487 | Resource group is unsupported with DISABLE_PSI_THREAD. | ||
| 3488 | The below #ifdef is required for compilation when DISABLE_PSI_THREAD | ||
| 3489 | is enabled. | ||
| 3490 | */ | ||
| 3491 | #ifdef HAVE_PSI_THREAD_INTERFACE | ||
| 3492 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | pfs_thread_id = PSI_THREAD_CALL(get_current_thread_internal_id)(); |
| 3493 | #endif // HAVE_PSI_THREAD_INTERFACE | ||
| 3494 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | push_warning_printf(thd, Sql_condition::SL_WARNING, |
| 3495 | ER_RESOURCE_GROUP_BIND_FAILED, | ||
| 3496 | ER_THD(thd, ER_RESOURCE_GROUP_BIND_FAILED), | ||
| 3497 | res_grp_name, pfs_thread_id, | ||
| 3498 | "System resource group can't be bound" | ||
| 3499 | " with a session thread"); | ||
| 3500 | 3 | break; | |
| 3501 | } | ||
| 3502 | 1 | case WARN_RESOURCE_GROUP_NOT_EXISTS: | |
| 3503 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | push_warning_printf( |
| 3504 | thd, Sql_condition::SL_WARNING, ER_RESOURCE_GROUP_NOT_EXISTS, | ||
| 3505 | ER_THD(thd, ER_RESOURCE_GROUP_NOT_EXISTS), res_grp_name); | ||
| 3506 | 1 | break; | |
| 3507 | ✗ | case WARN_RESOURCE_GROUP_ACCESS_DENIED: | |
| 3508 | ✗ | push_warning_printf(thd, Sql_condition::SL_WARNING, | |
| 3509 | ER_SPECIFIC_ACCESS_DENIED_ERROR, | ||
| 3510 | ER_THD(thd, ER_SPECIFIC_ACCESS_DENIED_ERROR), | ||
| 3511 | "SUPER OR RESOURCE_GROUP_ADMIN OR " | ||
| 3512 | "RESOURCE_GROUP_USER"); | ||
| 3513 | } | ||
| 3514 | 4 | thd->resource_group_ctx()->m_warn = 0; | |
| 3515 | 4 | res_grp_name[0] = '\0'; | |
| 3516 | } | ||
| 3517 | |||
| 3518 |
2/2✓ Branch 0 taken 536265 times.
✓ Branch 1 taken 20853916 times.
|
21391137 | if (unlikely(thd->slave_thread)) { |
| 3519 |
3/4✓ Branch 0 taken 536523 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 286 times.
✓ Branch 3 taken 536237 times.
|
536265 | if (!check_database_filters(thd, thd->db().str, lex->sql_command)) { |
| 3520 |
1/2✓ Branch 0 taken 286 times.
✗ Branch 1 not taken.
|
286 | binlog_gtid_end_transaction(thd); |
| 3521 | 286 | return 0; | |
| 3522 | } | ||
| 3523 | |||
| 3524 |
2/2✓ Branch 0 taken 903 times.
✓ Branch 1 taken 535334 times.
|
536237 | if (lex->sql_command == SQLCOM_DROP_TRIGGER) { |
| 3525 | /* | ||
| 3526 | When dropping a trigger, we need to load its table name | ||
| 3527 | before checking slave filter rules. | ||
| 3528 | */ | ||
| 3529 | 903 | TABLE_LIST *trigger_table = nullptr; | |
| 3530 |
1/2✓ Branch 0 taken 903 times.
✗ Branch 1 not taken.
|
903 | (void)get_table_for_trigger(thd, lex->spname->m_db, lex->spname->m_name, |
| 3531 | true, &trigger_table); | ||
| 3532 |
2/2✓ Branch 0 taken 869 times.
✓ Branch 1 taken 34 times.
|
903 | if (trigger_table != nullptr) { |
| 3533 | 869 | lex->add_to_query_tables(trigger_table); | |
| 3534 | 869 | all_tables = trigger_table; | |
| 3535 | } else { | ||
| 3536 | /* | ||
| 3537 | If table name cannot be loaded, | ||
| 3538 | it means the trigger does not exists possibly because | ||
| 3539 | CREATE TRIGGER was previously skipped for this trigger | ||
| 3540 | according to slave filtering rules. | ||
| 3541 | Returning success without producing any errors in this case. | ||
| 3542 | */ | ||
| 3543 |
1/2✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
|
34 | binlog_gtid_end_transaction(thd); |
| 3544 | 34 | return 0; | |
| 3545 | } | ||
| 3546 | |||
| 3547 | // force searching in slave.cc:tables_ok() | ||
| 3548 | 869 | all_tables->updating = true; | |
| 3549 | } | ||
| 3550 | |||
| 3551 | /* | ||
| 3552 | For fix of BUG#37051, the master stores the table map for update | ||
| 3553 | in the Query_log_event, and the value is assigned to | ||
| 3554 | thd->table_map_for_update before executing the update | ||
| 3555 | query. | ||
| 3556 | |||
| 3557 | If thd->table_map_for_update is set, then we are | ||
| 3558 | replicating from a new master, we can use this value to apply | ||
| 3559 | filter rules without opening all the tables. However If | ||
| 3560 | thd->table_map_for_update is not set, then we are | ||
| 3561 | replicating from an old master, so we just skip this and | ||
| 3562 | continue with the old method. And of course, the bug would still | ||
| 3563 | exist for old masters. | ||
| 3564 | */ | ||
| 3565 |
4/4✓ Branch 0 taken 481 times.
✓ Branch 1 taken 535722 times.
✓ Branch 2 taken 479 times.
✓ Branch 3 taken 2 times.
|
536203 | if (lex->sql_command == SQLCOM_UPDATE_MULTI && thd->table_map_for_update) { |
| 3566 | 479 | table_map table_map_for_update = thd->table_map_for_update; | |
| 3567 | 479 | uint nr = 0; | |
| 3568 | TABLE_LIST *table; | ||
| 3569 |
2/2✓ Branch 0 taken 5081 times.
✓ Branch 1 taken 479 times.
|
5560 | for (table = all_tables; table; table = table->next_global, nr++) { |
| 3570 |
2/2✓ Branch 0 taken 2657 times.
✓ Branch 1 taken 2424 times.
|
5081 | if (table_map_for_update & ((table_map)1 << nr)) |
| 3571 | 2657 | table->updating = true; | |
| 3572 | else | ||
| 3573 | 2424 | table->updating = false; | |
| 3574 | } | ||
| 3575 | |||
| 3576 |
3/4✓ Branch 0 taken 479 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 441 times.
|
479 | if (all_tables_not_ok(thd, all_tables)) { |
| 3577 | /* we warn the slave SQL thread */ | ||
| 3578 |
1/2✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
|
38 | my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); |
| 3579 |
1/2✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
|
38 | binlog_gtid_end_transaction(thd); |
| 3580 | 38 | return 0; | |
| 3581 | } | ||
| 3582 | |||
| 3583 |
2/2✓ Branch 0 taken 4957 times.
✓ Branch 1 taken 441 times.
|
5398 | for (table = all_tables; table; table = table->next_global) |
| 3584 | 4957 | table->updating = true; | |
| 3585 | } | ||
| 3586 | |||
| 3587 | /* | ||
| 3588 | Check if statement should be skipped because of slave filtering | ||
| 3589 | rules | ||
| 3590 | |||
| 3591 | Exceptions are: | ||
| 3592 | - UPDATE MULTI: For this statement, we want to check the filtering | ||
| 3593 | rules later in the code | ||
| 3594 | - SET: we always execute it (Not that many SET commands exists in | ||
| 3595 | the binary log anyway -- only 4.1 masters write SET statements, | ||
| 3596 | in 5.0 there are no SET statements in the binary log) | ||
| 3597 | - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we | ||
| 3598 | have stale files on slave caused by exclusion of one tmp table). | ||
| 3599 | */ | ||
| 3600 | 1607164 | if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) && | |
| 3601 |
2/2✓ Branch 0 taken 533792 times.
✓ Branch 1 taken 1501 times.
|
535293 | !(lex->sql_command == SQLCOM_SET_OPTION) && |
| 3602 |
4/4✓ Branch 0 taken 10610 times.
✓ Branch 1 taken 523182 times.
✓ Branch 2 taken 862 times.
✓ Branch 3 taken 9748 times.
|
533792 | !(lex->sql_command == SQLCOM_DROP_TABLE && lex->drop_temporary && |
| 3603 |
6/6✓ Branch 0 taken 535293 times.
✓ Branch 1 taken 872 times.
✓ Branch 2 taken 597 times.
✓ Branch 3 taken 265 times.
✓ Branch 4 taken 281 times.
✓ Branch 5 taken 535425 times.
|
1071596 | lex->drop_if_exists) && |
| 3604 |
3/4✓ Branch 0 taken 533068 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 281 times.
✓ Branch 3 taken 532787 times.
|
533527 | all_tables_not_ok(thd, all_tables)) { |
| 3605 | /* we warn the slave SQL thread */ | ||
| 3606 |
1/2✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 | my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); |
| 3607 |
1/2✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 | binlog_gtid_end_transaction(thd); |
| 3608 | 281 | return 0; | |
| 3609 | } | ||
| 3610 | /* | ||
| 3611 | Execute deferred events first | ||
| 3612 | */ | ||
| 3613 |
2/4✓ Branch 0 taken 536120 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 536120 times.
|
535425 | if (slave_execute_deferred_events(thd)) return -1; |
| 3614 | |||
| 3615 |
1/2✓ Branch 0 taken 535943 times.
✗ Branch 1 not taken.
|
536120 | int ret = launch_hook_trans_begin(thd, all_tables); |
| 3616 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 535943 times.
|
535943 | if (ret) { |
| 3617 | ✗ | my_error(ret, MYF(0)); | |
| 3618 | ✗ | return -1; | |
| 3619 | } | ||
| 3620 | |||
| 3621 | } else { | ||
| 3622 |
1/2✓ Branch 0 taken 20854482 times.
✗ Branch 1 not taken.
|
20853916 | int ret = launch_hook_trans_begin(thd, all_tables); |
| 3623 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 20854466 times.
|
20854482 | if (ret) { |
| 3624 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | my_error(ret, MYF(0)); |
| 3625 | 16 | return -1; | |
| 3626 | } | ||
| 3627 | |||
| 3628 | /* | ||
| 3629 | When option readonly is set deny operations which change non-temporary | ||
| 3630 | tables. Except for the replication thread and the 'super' users. | ||
| 3631 | */ | ||
| 3632 |
3/4✓ Branch 0 taken 20854261 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
✓ Branch 3 taken 20854188 times.
|
20854466 | if (deny_updates_if_read_only_option(thd, all_tables)) { |
| 3633 | 73 | thd->diff_access_denied_errors++; | |
| 3634 |
1/2✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
|
73 | err_readonly(thd); |
| 3635 | 73 | return -1; | |
| 3636 | } | ||
| 3637 | } /* endif unlikely slave */ | ||
| 3638 | |||
| 3639 | 21390131 | thd->status_var.com_stat[lex->sql_command]++; | |
| 3640 | |||
| 3641 | Opt_trace_start ots(thd, all_tables, lex->sql_command, &lex->var_list, | ||
| 3642 |
1/2✓ Branch 0 taken 21390762 times.
✗ Branch 1 not taken.
|
21390718 | thd->query().str, thd->query().length, nullptr, |
| 3643 |
2/4✓ Branch 0 taken 21390718 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21390874 times.
✗ Branch 3 not taken.
|
64170034 | thd->variables.character_set_client); |
| 3644 | |||
| 3645 |
1/2✓ Branch 0 taken 21390059 times.
✗ Branch 1 not taken.
|
42779699 | Opt_trace_object trace_command(&thd->opt_trace); |
| 3646 |
1/2✓ Branch 0 taken 21390444 times.
✗ Branch 1 not taken.
|
42778920 | Opt_trace_array trace_command_steps(&thd->opt_trace, "steps"); |
| 3647 | |||
| 3648 | #ifdef WITH_WSREP | ||
| 3649 |
8/8✓ Branch 0 taken 21390250 times.
✓ Branch 1 taken 194 times.
✓ Branch 2 taken 2904866 times.
✓ Branch 3 taken 18485384 times.
✓ Branch 4 taken 329145 times.
✓ Branch 5 taken 2575721 times.
✓ Branch 6 taken 279392 times.
✓ Branch 7 taken 49753 times.
|
21390444 | if (WSREP(thd)) { |
| 3650 | /* | ||
| 3651 | * bail out if DB snapshot has not been installed. We however, | ||
| 3652 | * allow SET and SHOW queries and reads from information schema | ||
| 3653 | * and dirty reads (if configured) | ||
| 3654 | */ | ||
| 3655 | 804956 | if (!thd->wsrep_applier && | |
| 3656 |
5/6✓ Branch 0 taken 246090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 244487 times.
✓ Branch 3 taken 1603 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 244480 times.
|
246052 | !(wsrep_ready_get() && wsrep_reject_queries == WSREP_REJECT_NONE) && |
| 3657 |
2/2✓ Branch 0 taken 58 times.
✓ Branch 1 taken 1552 times.
|
1610 | !(thd->variables.wsrep_dirty_reads && |
| 3658 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 53 times.
|
58 | (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) == 0) && |
| 3659 |
3/4✓ Branch 0 taken 1557 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 580 times.
✓ Branch 3 taken 977 times.
|
1557 | !wsrep_tables_accessible_when_detached(all_tables) && |
| 3660 |
2/2✓ Branch 0 taken 364 times.
✓ Branch 1 taken 216 times.
|
580 | lex->sql_command != SQLCOM_SET_OPTION && |
| 3661 |
2/2✓ Branch 0 taken 360 times.
✓ Branch 1 taken 4 times.
|
364 | lex->sql_command != SQLCOM_SHUTDOWN && |
| 3662 |
7/8✓ Branch 0 taken 246052 times.
✓ Branch 1 taken 33340 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 346 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 279457 times.
|
525835 | !(lex->sql_command == SQLCOM_SELECT && !all_tables) && |
| 3663 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 336 times.
|
309 | !wsrep_is_show_query(lex->sql_command)) { |
| 3664 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | my_message(ER_UNKNOWN_COM_ERROR, |
| 3665 | "WSREP has not yet prepared node for application use", MYF(0)); | ||
| 3666 | 17 | return -1; | |
| 3667 | } | ||
| 3668 |
3/4✓ Branch 0 taken 279524 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 279521 times.
|
279457 | if (block_write_while_in_rolling_upgrade(thd)) { |
| 3669 | 3 | return -1; | |
| 3670 | } | ||
| 3671 | } | ||
| 3672 | #endif /* WITH_WSREP */ | ||
| 3673 | |||
| 3674 |
6/6✓ Branch 0 taken 18433606 times.
✓ Branch 1 taken 2956967 times.
✓ Branch 2 taken 114693 times.
✓ Branch 3 taken 18318780 times.
✓ Branch 4 taken 114721 times.
✓ Branch 5 taken 21275719 times.
|
21390573 | if (lex->m_sql_cmd && lex->m_sql_cmd->owner()) |
| 3675 |
1/2✓ Branch 0 taken 114468 times.
✗ Branch 1 not taken.
|
114721 | lex->m_sql_cmd->owner()->trace_parameter_types(); |
| 3676 | |||
| 3677 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21389755 times.
|
21390187 | assert(thd->get_transaction()->cannot_safely_rollback( |
| 3678 | Transaction_ctx::STMT) == false); | ||
| 3679 | |||
| 3680 |
4/6✓ Branch 0 taken 21390487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21365868 times.
✓ Branch 3 taken 132 times.
✓ Branch 4 taken 24684 times.
✗ Branch 5 not taken.
|
21389755 | switch (gtid_pre_statement_checks(thd)) { |
| 3681 | 21365868 | case GTID_STATEMENT_EXECUTE: | |
| 3682 | 21365868 | break; | |
| 3683 | 132 | case GTID_STATEMENT_CANCEL: | |
| 3684 | 132 | return -1; | |
| 3685 | 24684 | case GTID_STATEMENT_SKIP: | |
| 3686 |
1/2✓ Branch 0 taken 24684 times.
✗ Branch 1 not taken.
|
24684 | my_ok(thd); |
| 3687 |
1/2✓ Branch 0 taken 24684 times.
✗ Branch 1 not taken.
|
24684 | binlog_gtid_end_transaction(thd); |
| 3688 | 24684 | return 0; | |
| 3689 | } | ||
| 3690 | |||
| 3691 |
2/2✓ Branch 0 taken 36056 times.
✓ Branch 1 taken 21329615 times.
|
21365671 | if (thd->variables.require_row_format) { |
| 3692 |
3/4✓ Branch 0 taken 36039 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 36028 times.
|
36056 | if (evaluate_command_row_only_restrictions(thd)) { |
| 3693 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | my_error(ER_CLIENT_QUERY_FAILURE_INVALID_NON_ROW_FORMAT, MYF(0)); |
| 3694 | 11 | return -1; | |
| 3695 | } | ||
| 3696 | } | ||
| 3697 | |||
| 3698 | /* | ||
| 3699 | End a active transaction so that this command will have it's | ||
| 3700 | own transaction and will also sync the binary log. If a DDL is | ||
| 3701 | not run in it's own transaction it may simply never appear on | ||
| 3702 | the slave in case the outside transaction rolls back. | ||
| 3703 | */ | ||
| 3704 |
3/4✓ Branch 0 taken 21366015 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1266051 times.
✓ Branch 3 taken 20099964 times.
|
21365643 | if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_BEGIN)) { |
| 3705 | /* | ||
| 3706 | Note that this should never happen inside of stored functions | ||
| 3707 | or triggers as all such statements prohibited there. | ||
| 3708 | */ | ||
| 3709 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1266051 times.
|
1266051 | assert(!thd->in_sub_stmt); |
| 3710 | /* Statement transaction still should not be started. */ | ||
| 3711 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1266047 times.
|
1266051 | assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT)); |
| 3712 | |||
| 3713 | /* | ||
| 3714 | Implicit commit is not allowed with an active XA transaction. | ||
| 3715 | In this case we should not release metadata locks as the XA transaction | ||
| 3716 | will not be rolled back. Therefore we simply return here. | ||
| 3717 | */ | ||
| 3718 |
3/4✓ Branch 0 taken 1266057 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1266055 times.
|
1266047 | if (trans_check_state(thd)) return -1; |
| 3719 | |||
| 3720 | /* Commit the normal transaction if one is active. */ | ||
| 3721 | #ifdef WITH_WSREP | ||
| 3722 |
2/4✓ Branch 0 taken 1266054 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1266054 times.
|
1266055 | if (trans_commit_implicit(thd)) { |
| 3723 | ✗ | thd->mdl_context.release_transactional_locks(); | |
| 3724 | ✗ | WSREP_DEBUG( | |
| 3725 | "Transaction implicit commit failed" | ||
| 3726 | " MDL released: %u", | ||
| 3727 | thd->thread_id()); | ||
| 3728 | ✗ | return -1; | |
| 3729 | } | ||
| 3730 | #else | ||
| 3731 | if (trans_commit_implicit(thd)) return -1; | ||
| 3732 | #endif /* WITH_WSREP */ | ||
| 3733 | |||
| 3734 | /* Release metadata locks acquired in this transaction. */ | ||
| 3735 |
1/2✓ Branch 0 taken 1266051 times.
✗ Branch 1 not taken.
|
1266054 | thd->mdl_context.release_transactional_locks(); |
| 3736 | |||
| 3737 | #ifdef WITH_WSREP | ||
| 3738 | /* | ||
| 3739 | Clean up the previous transaction on implicit commit. | ||
| 3740 | If it was not empty transaction, it already has been commited | ||
| 3741 | to Galera in trans_commit_implicit(). | ||
| 3742 | If it was empty transaction (no work sets), trans_commit_implicit() | ||
| 3743 | did nothing to Galera, so we need to commit empty transaction. | ||
| 3744 | */ | ||
| 3745 |
3/4✓ Branch 0 taken 1266039 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1258523 times.
✓ Branch 3 taken 7516 times.
|
1266051 | if (wsrep_thd_is_local(thd)) { |
| 3746 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1258520 times.
|
1258523 | if (wsrep_has_changes(thd)) { |
| 3747 |
2/4✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
|
9 | if (wsrep_after_statement(thd)) { |
| 3748 | ✗ | return -1; | |
| 3749 | } | ||
| 3750 | } else { | ||
| 3751 |
1/2✓ Branch 0 taken 1258462 times.
✗ Branch 1 not taken.
|
1258520 | wsrep_commit_empty(thd, true); |
| 3752 | } | ||
| 3753 | } | ||
| 3754 | #endif /* WITH_WSREP */ | ||
| 3755 | } | ||
| 3756 | |||
| 3757 |
3/4✓ Branch 0 taken 19284981 times.
✓ Branch 1 taken 2079956 times.
✓ Branch 2 taken 19286013 times.
✗ Branch 3 not taken.
|
21365951 | DEBUG_SYNC(thd, "after_implicit_pre_commit"); |
| 3758 | |||
| 3759 |
3/4✓ Branch 0 taken 21366061 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 519 times.
✓ Branch 3 taken 21365542 times.
|
21365969 | if (gtid_pre_statement_post_implicit_commit_checks(thd)) return -1; |
| 3760 | |||
| 3761 |
7/8✓ Branch 0 taken 13650129 times.
✓ Branch 1 taken 7715413 times.
✓ Branch 2 taken 13650119 times.
✓ Branch 3 taken 7715423 times.
✓ Branch 4 taken 21365075 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 21365068 times.
|
21365542 | if (mysql_audit_notify(thd, |
| 3762 | first_level ? MYSQL_AUDIT_QUERY_START | ||
| 3763 | : MYSQL_AUDIT_QUERY_NESTED_START, | ||
| 3764 | first_level ? "MYSQL_AUDIT_QUERY_START" | ||
| 3765 | : "MYSQL_AUDIT_QUERY_NESTED_START")) { | ||
| 3766 | 7 | return 1; | |
| 3767 | } | ||
| 3768 | |||
| 3769 | #ifndef NDEBUG | ||
| 3770 |
2/2✓ Branch 0 taken 19860531 times.
✓ Branch 1 taken 1504537 times.
|
21365068 | if (lex->sql_command != SQLCOM_SET_OPTION) |
| 3771 |
3/4✓ Branch 0 taken 17828230 times.
✓ Branch 1 taken 2031859 times.
✓ Branch 2 taken 17828818 times.
✗ Branch 3 not taken.
|
19860531 | DEBUG_SYNC(thd, "before_execute_sql_command"); |
| 3772 | #endif | ||
| 3773 | |||
| 3774 | /* | ||
| 3775 | Start a new transaction if CREATE TABLE has START TRANSACTION clause. | ||
| 3776 | Disable binlog so that the BEGIN is not logged in binlog. | ||
| 3777 | */ | ||
| 3778 |
4/4✓ Branch 0 taken 878933 times.
✓ Branch 1 taken 20486281 times.
✓ Branch 2 taken 70 times.
✓ Branch 3 taken 878863 times.
|
21365214 | if (lex->create_info && lex->create_info->m_transactional_ddl && |
| 3779 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 47 times.
|
70 | !thd->slave_thread) { |
| 3780 | 23 | Disable_binlog_guard binlog_guard(thd); | |
| 3781 |
2/4✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
|
23 | if (trans_begin(thd, MYSQL_START_TRANS_OPT_READ_WRITE)) return true; |
| 3782 |
1/2✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
|
23 | } |
| 3783 | |||
| 3784 | /* | ||
| 3785 | For statements which need this, prevent InnoDB from automatically | ||
| 3786 | committing InnoDB transaction each time data-dictionary tables are | ||
| 3787 | closed after being updated. | ||
| 3788 | */ | ||
| 3789 | Disable_autocommit_guard autocommit_guard( | ||
| 3790 |
2/2✓ Branch 0 taken 1125898 times.
✓ Branch 1 taken 14996 times.
|
22505967 | sqlcom_needs_autocommit_off(lex) && !thd->is_plugin_fake_ddl() ? thd |
| 3791 |
2/2✓ Branch 0 taken 1140753 times.
✓ Branch 1 taken 20223794 times.
|
43869493 | : nullptr); |
| 3792 | |||
| 3793 | /* | ||
| 3794 | Check if we are in a read-only transaction and we're trying to | ||
| 3795 | execute a statement which should always be disallowed in such cases. | ||
| 3796 | |||
| 3797 | Note that this check is done after any implicit commits. | ||
| 3798 | */ | ||
| 3799 |
2/2✓ Branch 0 taken 249 times.
✓ Branch 1 taken 21363820 times.
|
21364069 | if (thd->tx_read_only && |
| 3800 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 228 times.
|
249 | (sql_command_flags[lex->sql_command] & CF_DISALLOW_IN_RO_TRANS)) { |
| 3801 | 21 | thd->diff_access_denied_errors++; | |
| 3802 |
1/2✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
|
21 | my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0)); |
| 3803 | 21 | goto error; | |
| 3804 | } | ||
| 3805 | |||
| 3806 | /* | ||
| 3807 | Close tables open by HANDLERs before executing DDL statement | ||
| 3808 | which is going to affect those tables. | ||
| 3809 | |||
| 3810 | This should happen before temporary tables are pre-opened as | ||
| 3811 | otherwise we will get errors about attempt to re-open tables | ||
| 3812 | if table to be changed is open through HANDLER. | ||
| 3813 | |||
| 3814 | Note that even although this is done before any privilege | ||
| 3815 | checks there is no security problem here as closing open | ||
| 3816 | HANDLER doesn't require any privileges anyway. | ||
| 3817 | */ | ||
| 3818 |
2/2✓ Branch 0 taken 955801 times.
✓ Branch 1 taken 20408247 times.
|
21364048 | if (sql_command_flags[lex->sql_command] & CF_HA_CLOSE) |
| 3819 |
1/2✓ Branch 0 taken 955801 times.
✗ Branch 1 not taken.
|
955801 | mysql_ha_rm_tables(thd, all_tables); |
| 3820 | |||
| 3821 | /* | ||
| 3822 | Check that the command is allowed on the PROTOCOL_PLUGIN | ||
| 3823 | */ | ||
| 3824 |
5/6✓ Branch 0 taken 21363794 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 105357 times.
✓ Branch 3 taken 21258437 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 21363779 times.
|
21469405 | if (thd->get_protocol()->type() == Protocol::PROTOCOL_PLUGIN && |
| 3825 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 105342 times.
|
105357 | !(sql_command_flags[lex->sql_command] & CF_ALLOW_PROTOCOL_PLUGIN)) { |
| 3826 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | my_error(ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED, MYF(0)); |
| 3827 | 15 | goto error; | |
| 3828 | } | ||
| 3829 | |||
| 3830 | /* | ||
| 3831 | Pre-open temporary tables to simplify privilege checking | ||
| 3832 | for statements which need this. | ||
| 3833 | */ | ||
| 3834 |
2/2✓ Branch 0 taken 19347065 times.
✓ Branch 1 taken 2016714 times.
|
21363779 | if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES) { |
| 3835 |
3/4✓ Branch 0 taken 19347301 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 19347276 times.
|
19347065 | if (open_temporary_tables(thd, all_tables)) goto error; |
| 3836 | } | ||
| 3837 | |||
| 3838 | // Save original info for EXPLAIN FOR CONNECTION | ||
| 3839 |
2/2✓ Branch 0 taken 21239945 times.
✓ Branch 1 taken 124045 times.
|
21363990 | if (!thd->in_sub_stmt) |
| 3840 | 42479988 | thd->query_plan.set_query_plan(lex->sql_command, lex, | |
| 3841 |
1/2✓ Branch 0 taken 21241516 times.
✗ Branch 1 not taken.
|
21239945 | !thd->stmt_arena->is_regular()); |
| 3842 | |||
| 3843 | /* Update system variables specified in SET_VAR hints. */ | ||
| 3844 |
4/4✓ Branch 0 taken 7751 times.
✓ Branch 1 taken 21357810 times.
✓ Branch 2 taken 6736 times.
✓ Branch 3 taken 1015 times.
|
21365561 | if (lex->opt_hints_global && lex->opt_hints_global->sys_var_hint) |
| 3845 |
1/2✓ Branch 0 taken 6736 times.
✗ Branch 1 not taken.
|
6736 | lex->opt_hints_global->sys_var_hint->update_vars(thd); |
| 3846 | |||
| 3847 | /* Check if the statement fulfill the requirements on ACL CACHE */ | ||
| 3848 |
3/4✓ Branch 0 taken 21364532 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 21364530 times.
|
21365561 | if (!command_satisfy_acl_cache_requirement(lex->sql_command)) { |
| 3849 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); |
| 3850 | 2 | goto error; | |
| 3851 | } | ||
| 3852 | |||
| 3853 |
9/10✓ Branch 0 taken 21364393 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✓ Branch 3 taken 21364317 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 74 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 75 times.
|
21364530 | DBUG_EXECUTE_IF( |
| 3854 | "force_rollback_in_replica_on_transactional_ddl_commit", | ||
| 3855 | if (thd->m_transactional_ddl.inited() && | ||
| 3856 | thd->lex->sql_command == SQLCOM_COMMIT) { | ||
| 3857 | lex->sql_command = SQLCOM_ROLLBACK; | ||
| 3858 | }); | ||
| 3859 | #ifdef WITH_WSREP | ||
| 3860 | /* | ||
| 3861 | Always start a new transaction for a wsrep THD unless the | ||
| 3862 | current command is DDL or explicit BEGIN. This will guarantee that | ||
| 3863 | the THD is BF abortable even if it does not generate any | ||
| 3864 | changes and takes only read locks. If the statement does not | ||
| 3865 | start a multi STMT transaction, the wsrep_transaction is | ||
| 3866 | committed as empty at the end of this function. | ||
| 3867 | |||
| 3868 | Transaction is started for BEGIN in trans_begin(), for DDL the | ||
| 3869 | implicit commit took care of committing previous transaction | ||
| 3870 | above and a new transaction should not be started. | ||
| 3871 | |||
| 3872 | Do not start transaction for stored procedures, it will be handled | ||
| 3873 | internally in SP processing. | ||
| 3874 | */ | ||
| 3875 |
9/10✓ Branch 0 taken 2904839 times.
✓ Branch 1 taken 18459298 times.
✓ Branch 2 taken 329123 times.
✓ Branch 3 taken 2575716 times.
✓ Branch 4 taken 279406 times.
✓ Branch 5 taken 49717 times.
✓ Branch 6 taken 279380 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 245971 times.
✓ Branch 9 taken 33409 times.
|
21364137 | if (WSREP(thd) && wsrep_thd_is_local(thd) && |
| 3876 |
4/4✓ Branch 0 taken 245352 times.
✓ Branch 1 taken 619 times.
✓ Branch 2 taken 236209 times.
✓ Branch 3 taken 9143 times.
|
245971 | lex->sql_command != SQLCOM_BEGIN && lex->sql_command != SQLCOM_CALL && |
| 3877 |
6/6✓ Branch 0 taken 21364137 times.
✓ Branch 1 taken 256 times.
✓ Branch 2 taken 236130 times.
✓ Branch 3 taken 79 times.
✓ Branch 4 taken 184265 times.
✓ Branch 5 taken 21180102 times.
|
42964634 | lex->sql_command != SQLCOM_EXECUTE && |
| 3878 |
2/2✓ Branch 0 taken 184258 times.
✓ Branch 1 taken 51872 times.
|
236130 | !(sql_command_flags[lex->sql_command] & CF_AUTO_COMMIT_TRANS)) { |
| 3879 |
1/2✓ Branch 0 taken 184253 times.
✗ Branch 1 not taken.
|
184265 | wsrep_start_trx_if_not_started(thd); |
| 3880 | } | ||
| 3881 | #endif /* WITH_WSREP */ | ||
| 3882 | |||
| 3883 | /* | ||
| 3884 | We do not flag "is DML" (TX_STMT_DML) here as replication expects us to | ||
| 3885 | test for LOCK TABLE etc. first. To rephrase, we try not to set TX_STMT_DML | ||
| 3886 | until we have the MDL, and LOCK TABLE could massively delay this. | ||
| 3887 | */ | ||
| 3888 | |||
| 3889 |
58/59✓ Branch 0 taken 48128 times.
✓ Branch 1 taken 115461 times.
✓ Branch 2 taken 42775 times.
✓ Branch 3 taken 14343 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 111 times.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 7865 times.
✓ Branch 8 taken 2227 times.
✓ Branch 9 taken 2053 times.
✓ Branch 10 taken 7030 times.
✓ Branch 11 taken 5884 times.
✓ Branch 12 taken 10000 times.
✓ Branch 13 taken 25623 times.
✓ Branch 14 taken 7894225 times.
✓ Branch 15 taken 352708 times.
✓ Branch 16 taken 678214 times.
✓ Branch 17 taken 160725 times.
✓ Branch 18 taken 89892 times.
✓ Branch 19 taken 1504619 times.
✓ Branch 20 taken 922 times.
✓ Branch 21 taken 4453 times.
✓ Branch 22 taken 2867 times.
✓ Branch 23 taken 35 times.
✓ Branch 24 taken 254 times.
✓ Branch 25 taken 79 times.
✓ Branch 26 taken 90 times.
✓ Branch 27 taken 15607 times.
✓ Branch 28 taken 6136 times.
✓ Branch 29 taken 975 times.
✓ Branch 30 taken 1142 times.
✓ Branch 31 taken 500 times.
✓ Branch 32 taken 205 times.
✓ Branch 33 taken 6788 times.
✓ Branch 34 taken 5621 times.
✓ Branch 35 taken 523 times.
✓ Branch 36 taken 1698 times.
✓ Branch 37 taken 12918 times.
✓ Branch 38 taken 26040 times.
✓ Branch 39 taken 23156 times.
✓ Branch 40 taken 2564 times.
✓ Branch 41 taken 1141 times.
✓ Branch 42 taken 355100 times.
✓ Branch 43 taken 273657 times.
✓ Branch 44 taken 10716 times.
✓ Branch 45 taken 38 times.
✓ Branch 46 taken 4286 times.
✓ Branch 47 taken 8288 times.
✓ Branch 48 taken 36017 times.
✓ Branch 49 taken 388 times.
✓ Branch 50 taken 37874 times.
✓ Branch 51 taken 67480 times.
✓ Branch 52 taken 4822 times.
✓ Branch 53 taken 23839 times.
✓ Branch 54 taken 3702 times.
✓ Branch 55 taken 158956 times.
✓ Branch 56 taken 9301005 times.
✓ Branch 57 taken 2543 times.
✗ Branch 58 not taken.
|
21364355 | switch (lex->sql_command) { |
| 3890 | 48128 | case SQLCOM_PREPARE: { | |
| 3891 |
1/2✓ Branch 0 taken 48126 times.
✗ Branch 1 not taken.
|
48128 | mysql_sql_stmt_prepare(thd); |
| 3892 | 48126 | break; | |
| 3893 | } | ||
| 3894 | 115461 | case SQLCOM_EXECUTE: { | |
| 3895 |
1/2✓ Branch 0 taken 115716 times.
✗ Branch 1 not taken.
|
115461 | mysql_sql_stmt_execute(thd); |
| 3896 | 115716 | break; | |
| 3897 | } | ||
| 3898 | 42775 | case SQLCOM_DEALLOCATE_PREPARE: { | |
| 3899 |
1/2✓ Branch 0 taken 42780 times.
✗ Branch 1 not taken.
|
42775 | mysql_sql_stmt_close(thd); |
| 3900 | 42780 | break; | |
| 3901 | } | ||
| 3902 | |||
| 3903 | 14343 | case SQLCOM_EMPTY_QUERY: | |
| 3904 |
1/2✓ Branch 0 taken 14343 times.
✗ Branch 1 not taken.
|
14343 | my_ok(thd); |
| 3905 | 14343 | break; | |
| 3906 | |||
| 3907 | 21 | case SQLCOM_HELP: | |
| 3908 |
1/2✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
|
21 | res = mysqld_help(thd, lex->help_arg); |
| 3909 | 21 | break; | |
| 3910 | |||
| 3911 | 111 | case SQLCOM_PURGE: { | |
| 3912 | 111 | Security_context *sctx = thd->security_context(); | |
| 3913 |
6/16✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 111 times.
✓ Branch 6 taken 111 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 111 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 111 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
111 | if (!sctx->check_access(SUPER_ACL) && |
| 3914 | ✗ | !sctx->has_global_grant(STRING_WITH_LEN("BINLOG_ADMIN")).first) { | |
| 3915 | ✗ | my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), | |
| 3916 | "SUPER or BINLOG_ADMIN"); | ||
| 3917 | ✗ | goto error; | |
| 3918 | } | ||
| 3919 | /* PURGE MASTER LOGS TO 'file' */ | ||
| 3920 |
1/2✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
|
111 | res = purge_source_logs_to_file(thd, lex->to_log); |
| 3921 | 111 | break; | |
| 3922 | } | ||
| 3923 | 26 | case SQLCOM_PURGE_BEFORE: { | |
| 3924 | Item *it; | ||
| 3925 | 26 | Security_context *sctx = thd->security_context(); | |
| 3926 |
6/16✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 26 times.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 26 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 26 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
26 | if (!sctx->check_access(SUPER_ACL) && |
| 3927 | ✗ | !sctx->has_global_grant(STRING_WITH_LEN("BINLOG_ADMIN")).first) { | |
| 3928 | ✗ | my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), | |
| 3929 | "SUPER or BINLOG_ADMIN"); | ||
| 3930 | ✗ | goto error; | |
| 3931 | } | ||
| 3932 | /* PURGE MASTER LOGS BEFORE 'data' */ | ||
| 3933 | 26 | it = lex->purge_value_list.head(); | |
| 3934 |
7/12✓ Branch 0 taken 16 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 26 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 26 times.
|
26 | if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1)) { |
| 3935 | ✗ | my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE"); | |
| 3936 | ✗ | goto error; | |
| 3937 | } | ||
| 3938 |
2/4✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | it = new Item_func_unix_timestamp(it); |
| 3939 | /* | ||
| 3940 | it is OK only emulate fix_fieds, because we need only | ||
| 3941 | value of constant | ||
| 3942 | */ | ||
| 3943 | 26 | it->quick_fix_field(); | |
| 3944 |
1/2✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
|
26 | time_t purge_time = static_cast<time_t>(it->val_int()); |
| 3945 |
2/4✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 26 times.
|
26 | if (thd->is_error()) goto error; |
| 3946 |
1/2✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
|
26 | res = purge_source_logs_before_date(thd, purge_time); |
| 3947 | 26 | break; | |
| 3948 | } | ||
| 3949 | 7865 | case SQLCOM_CHANGE_MASTER: { | |
| 3950 | 7865 | Security_context *sctx = thd->security_context(); | |
| 3951 |
6/16✓ Branch 0 taken 7865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7865 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7865 times.
✓ Branch 6 taken 7865 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7865 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 7865 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
7865 | if (!sctx->check_access(SUPER_ACL) && |
| 3952 | ✗ | !sctx->has_global_grant(STRING_WITH_LEN("REPLICATION_SLAVE_ADMIN")) | |
| 3953 | ✗ | .first) { | |
| 3954 | ✗ | my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), | |
| 3955 | "SUPER or REPLICATION_SLAVE_ADMIN"); | ||
| 3956 | ✗ | goto error; | |
| 3957 | } | ||
| 3958 |
1/2✓ Branch 0 taken 7865 times.
✗ Branch 1 not taken.
|
7865 | res = change_master_cmd(thd); |
| 3959 | 7865 | break; | |
| 3960 | } | ||
| 3961 | 2227 | case SQLCOM_START_GROUP_REPLICATION: { | |
| 3962 | 2227 | Security_context *sctx = thd->security_context(); | |
| 3963 |
8/16✓ Branch 0 taken 2227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2227 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 2221 times.
✓ Branch 6 taken 2227 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2227 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 2224 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
2233 | if (!sctx->check_access(SUPER_ACL) && |
| 3964 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | !sctx->has_global_grant(STRING_WITH_LEN("GROUP_REPLICATION_ADMIN")) |
| 3965 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
|
6 | .first) { |
| 3966 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), |
| 3967 | "SUPER or GROUP_REPLICATION_ADMIN"); | ||
| 3968 | 141 | goto error; | |
| 3969 | } | ||
| 3970 |
4/4✓ Branch 0 taken 27 times.
✓ Branch 1 taken 2197 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 25 times.
|
2224 | if (lex->slave_connection.password && !lex->slave_connection.user) { |
| 3971 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | my_error(ER_GROUP_REPLICATION_USER_MANDATORY_MSG, MYF(0)); |
| 3972 | 2 | goto error; | |
| 3973 | } | ||
| 3974 | |||
| 3975 | /* | ||
| 3976 | If the client thread has locked tables, a deadlock is possible. | ||
| 3977 | Assume that | ||
| 3978 | - the client thread does LOCK TABLE t READ. | ||
| 3979 | - then the client thread does START GROUP_REPLICATION. | ||
| 3980 | -try to make the server in super ready only mode | ||
| 3981 | -acquire MDL lock ownership which will be waiting for | ||
| 3982 | LOCK on table t to be released. | ||
| 3983 | To prevent that, refuse START GROUP_REPLICATION if the | ||
| 3984 | client thread has locked tables | ||
| 3985 | */ | ||
| 3986 |
6/6✓ Branch 0 taken 2221 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2220 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2220 times.
|
4442 | if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction() || |
| 3987 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2220 times.
|
2220 | thd->in_sub_stmt) { |
| 3988 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); |
| 3989 | 2 | goto error; | |
| 3990 | } | ||
| 3991 | |||
| 3992 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2219 times.
|
2220 | if (thd->variables.gtid_next.type == ASSIGNED_GTID && |
| 3993 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | thd->owned_gtid.sidno > 0) { |
| 3994 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_CANT_EXECUTE_COMMAND_WITH_ASSIGNED_GTID_NEXT, MYF(0)); |
| 3995 | 1 | early_error_on_rep_command = true; | |
| 3996 | 1 | goto error; | |
| 3997 | } | ||
| 3998 | |||
| 3999 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2218 times.
|
2219 | if (Clone_handler::is_provisioning()) { |
| 4000 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0), |
| 4001 | "START GROUP_REPLICATION", | ||
| 4002 | "This server is being provisioned by CLONE INSTANCE, " | ||
| 4003 | "please wait until it is complete."); | ||
| 4004 | 1 | goto error; | |
| 4005 | } | ||
| 4006 | |||
| 4007 | 2218 | char *error_message = nullptr; | |
| 4008 |
9/12✓ Branch 0 taken 2218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 2086 times.
|
2218 | res = group_replication_start(&error_message, thd); |
| 4009 | |||
| 4010 | // To reduce server dependency, server errors are not used here | ||
| 4011 | switch (res) { | ||
| 4012 | 100 | case 1: // GROUP_REPLICATION_CONFIGURATION_ERROR | |
| 4013 |
1/2✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
|
100 | my_error(ER_GROUP_REPLICATION_CONFIGURATION, MYF(0)); |
| 4014 | 100 | goto error; | |
| 4015 | 5 | case 2: // GROUP_REPLICATION_ALREADY_RUNNING | |
| 4016 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | my_error(ER_GROUP_REPLICATION_RUNNING, MYF(0)); |
| 4017 | 5 | goto error; | |
| 4018 | 9 | case 3: // GROUP_REPLICATION_REPLICATION_APPLIER_INIT_ERROR | |
| 4019 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | my_error(ER_GROUP_REPLICATION_APPLIER_INIT_ERROR, MYF(0)); |
| 4020 | 9 | goto error; | |
| 4021 | 14 | case 4: // GROUP_REPLICATION_COMMUNICATION_LAYER_SESSION_ERROR | |
| 4022 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | my_error(ER_GROUP_REPLICATION_COMMUNICATION_LAYER_SESSION_ERROR, |
| 4023 | MYF(0)); | ||
| 4024 | 14 | goto error; | |
| 4025 | 1 | case 5: // GROUP_REPLICATION_COMMUNICATION_LAYER_JOIN_ERROR | |
| 4026 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_GROUP_REPLICATION_COMMUNICATION_LAYER_JOIN_ERROR, MYF(0)); |
| 4027 | 1 | goto error; | |
| 4028 | ✗ | case 7: // GROUP_REPLICATION_MAX_GROUP_SIZE | |
| 4029 | ✗ | my_error(ER_GROUP_REPLICATION_MAX_GROUP_SIZE, MYF(0)); | |
| 4030 | ✗ | goto error; | |
| 4031 | 2 | case 8: // GROUP_REPLICATION_COMMAND_FAILURE | |
| 4032 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (error_message == nullptr) { |
| 4033 | ✗ | my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0), | |
| 4034 | "START GROUP_REPLICATION", | ||
| 4035 | "Please check error log for additional details."); | ||
| 4036 | } else { | ||
| 4037 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0), |
| 4038 | "START GROUP_REPLICATION", error_message); | ||
| 4039 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | my_free(error_message); |
| 4040 | } | ||
| 4041 | 2 | goto error; | |
| 4042 | ✗ | case 9: // GROUP_REPLICATION_SERVICE_MESSAGE_INIT_FAILURE | |
| 4043 | ✗ | my_error(ER_GRP_RPL_MESSAGE_SERVICE_INIT_FAILURE, MYF(0)); | |
| 4044 | ✗ | goto error; | |
| 4045 | 1 | case 10: // GROUP_REPLICATION_RECOVERY_CHANNEL_STILL_RUNNING | |
| 4046 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_GRP_RPL_RECOVERY_CHANNEL_STILL_RUNNING, MYF(0)); |
| 4047 | 1 | goto error; | |
| 4048 | } | ||
| 4049 |
1/2✓ Branch 0 taken 2086 times.
✗ Branch 1 not taken.
|
2086 | my_ok(thd); |
| 4050 | 2086 | res = 0; | |
| 4051 | 2086 | break; | |
| 4052 | } | ||
| 4053 | |||
| 4054 | 2053 | case SQLCOM_STOP_GROUP_REPLICATION: { | |
| 4055 | 2053 | Security_context *sctx = thd->security_context(); | |
| 4056 |
8/16✓ Branch 0 taken 2053 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2053 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 2047 times.
✓ Branch 6 taken 2053 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2053 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 2050 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
2059 | if (!sctx->check_access(SUPER_ACL) && |
| 4057 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | !sctx->has_global_grant(STRING_WITH_LEN("GROUP_REPLICATION_ADMIN")) |
| 4058 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
|
6 | .first) { |
| 4059 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), |
| 4060 | "SUPER or GROUP_REPLICATION_ADMIN"); | ||
| 4061 | 17 | goto error; | |
| 4062 | } | ||
| 4063 | |||
| 4064 | /* | ||
| 4065 | Please see explanation @SQLCOM_SLAVE_STOP case | ||
| 4066 | to know the reason for thd->locked_tables_mode in | ||
| 4067 | the below if condition. | ||
| 4068 | */ | ||
| 4069 |
6/6✓ Branch 0 taken 2049 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2048 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2048 times.
|
4098 | if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction() || |
| 4070 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2048 times.
|
2048 | thd->in_sub_stmt) { |
| 4071 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); |
| 4072 | 2 | goto error; | |
| 4073 | } | ||
| 4074 | |||
| 4075 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2047 times.
|
2048 | if (thd->variables.gtid_next.type == ASSIGNED_GTID && |
| 4076 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | thd->owned_gtid.sidno > 0) { |
| 4077 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_CANT_EXECUTE_COMMAND_WITH_ASSIGNED_GTID_NEXT, MYF(0)); |
| 4078 | 1 | early_error_on_rep_command = true; | |
| 4079 | 1 | goto error; | |
| 4080 | } | ||
| 4081 | |||
| 4082 | 2047 | char *error_message = nullptr; | |
| 4083 |
1/2✓ Branch 0 taken 2047 times.
✗ Branch 1 not taken.
|
2047 | res = group_replication_stop(&error_message); |
| 4084 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2040 times.
|
2047 | if (res == 1) // GROUP_REPLICATION_CONFIGURATION_ERROR |
| 4085 | { | ||
| 4086 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | my_error(ER_GROUP_REPLICATION_CONFIGURATION, MYF(0)); |
| 4087 | 7 | goto error; | |
| 4088 | } | ||
| 4089 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2039 times.
|
2040 | if (res == 6) // GROUP_REPLICATION_APPLIER_THREAD_TIMEOUT |
| 4090 | { | ||
| 4091 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_GROUP_REPLICATION_STOP_APPLIER_THREAD_TIMEOUT, MYF(0)); |
| 4092 | 1 | goto error; | |
| 4093 | } | ||
| 4094 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2036 times.
|
2039 | if (res == 8) // GROUP_REPLICATION_COMMAND_FAILURE |
| 4095 | { | ||
| 4096 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (error_message == nullptr) { |
| 4097 | ✗ | my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0), | |
| 4098 | "STOP GROUP_REPLICATION", | ||
| 4099 | "Please check error log for additonal details."); | ||
| 4100 | } else { | ||
| 4101 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | my_error(ER_GROUP_REPLICATION_COMMAND_FAILURE, MYF(0), |
| 4102 | "STOP GROUP_REPLICATION", error_message); | ||
| 4103 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | my_free(error_message); |
| 4104 | } | ||
| 4105 | 3 | goto error; | |
| 4106 | } | ||
| 4107 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2035 times.
|
2036 | if (res == 11) // GROUP_REPLICATION_STOP_WITH_RECOVERY_TIMEOUT |
| 4108 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | push_warning(thd, Sql_condition::SL_WARNING, |
| 4109 | ER_GRP_RPL_RECOVERY_CHANNEL_STILL_RUNNING, | ||
| 4110 | ER_THD(thd, ER_GRP_RPL_RECOVERY_CHANNEL_STILL_RUNNING)); | ||
| 4111 | |||
| 4112 | // Allow the command to commit any underlying transaction | ||
| 4113 | 2036 | lex->set_was_replication_command_executed(); | |
| 4114 | 2036 | thd->set_skip_readonly_check(); | |
| 4115 |
1/2✓ Branch 0 taken 2036 times.
✗ Branch 1 not taken.
|
2036 | my_ok(thd); |
| 4116 | 2036 | res = 0; | |
| 4117 | 2036 | break; | |
| 4118 | } | ||
| 4119 | |||
| 4120 | 7030 | case SQLCOM_SLAVE_START: { | |
| 4121 |
1/2✓ Branch 0 taken 7024 times.
✗ Branch 1 not taken.
|
7030 | res = start_slave_cmd(thd); |
| 4122 | 7024 | break; | |
| 4123 | } | ||
| 4124 | 5884 | case SQLCOM_SLAVE_STOP: { | |
| 4125 | /* | ||
| 4126 | If the client thread has locked tables, a deadlock is possible. | ||
| 4127 | Assume that | ||
| 4128 | - the client thread does LOCK TABLE t READ. | ||
| 4129 | - then the master updates t. | ||
| 4130 | - then the SQL slave thread wants to update t, | ||
| 4131 | so it waits for the client thread because t is locked by it. | ||
| 4132 | - then the client thread does SLAVE STOP. | ||
| 4133 | SLAVE STOP waits for the SQL slave thread to terminate its | ||
| 4134 | update t, which waits for the client thread because t is locked by it. | ||
| 4135 | To prevent that, refuse SLAVE STOP if the | ||
| 4136 | client thread has locked tables | ||
| 4137 | */ | ||
| 4138 |
3/4✓ Branch 0 taken 5884 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5881 times.
✓ Branch 3 taken 3 times.
|
11768 | if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction() || |
| 4139 |
5/6✓ Branch 0 taken 5884 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 5878 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 5878 times.
|
17652 | thd->global_read_lock.is_acquired() || |
| 4140 | 5881 | thd->backup_tables_lock.is_acquired()) { | |
| 4141 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); |
| 4142 | 6 | goto error; | |
| 4143 | } | ||
| 4144 | |||
| 4145 |
1/2✓ Branch 0 taken 5878 times.
✗ Branch 1 not taken.
|
5878 | res = stop_slave_cmd(thd); |
| 4146 | 5878 | break; | |
| 4147 | } | ||
| 4148 | 10000 | case SQLCOM_RENAME_TABLE: { | |
| 4149 |
2/4✓ Branch 0 taken 10000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10000 times.
✗ Branch 3 not taken.
|
10000 | assert(first_table == all_tables && first_table != nullptr); |
| 4150 | TABLE_LIST *table; | ||
| 4151 |
2/2✓ Branch 0 taken 18476 times.
✓ Branch 1 taken 9959 times.
|
28435 | for (table = first_table; table; table = table->next_local->next_local) { |
| 4152 |
1/2✓ Branch 0 taken 18476 times.
✗ Branch 1 not taken.
|
18476 | if (check_access(thd, ALTER_ACL | DROP_ACL, table->db, |
| 4153 | &table->grant.privilege, &table->grant.m_internal, | ||
| 4154 |
4/4✓ Branch 0 taken 18443 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 18443 times.
|
36919 | false, false) || |
| 4155 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18443 times.
|
18443 | check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db, |
| 4156 | 18443 | &table->next_local->grant.privilege, | |
| 4157 |
1/2✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
|
18443 | &table->next_local->grant.m_internal, false, false)) |
| 4158 | 41 | goto error; | |
| 4159 | |||
| 4160 |
1/2✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
|
18443 | TABLE_LIST old_list = table[0]; |
| 4161 |
1/2✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
|
18443 | TABLE_LIST new_list = table->next_local[0]; |
| 4162 | /* | ||
| 4163 | It's not clear what the above assignments actually want to | ||
| 4164 | accomplish. What we do know is that they do *not* want to copy the MDL | ||
| 4165 | requests, so we overwrite them with uninitialized request. | ||
| 4166 | */ | ||
| 4167 |
1/2✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
|
18443 | old_list.mdl_request = MDL_request(); |
| 4168 |
1/2✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
|
18443 | new_list.mdl_request = MDL_request(); |
| 4169 | |||
| 4170 |
1/2✓ Branch 0 taken 18443 times.
✗ Branch 1 not taken.
|
18443 | if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, false, 1, |
| 4171 |
4/4✓ Branch 0 taken 18436 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 18435 times.
|
36879 | false) || |
| 4172 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 18433 times.
|
18436 | (!test_all_bits(table->next_local->grant.privilege, |
| 4173 | 3 | INSERT_ACL | CREATE_ACL) && | |
| 4174 |
3/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
|
3 | check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, false, 1, |
| 4175 | false))) | ||
| 4176 | 8 | goto error; | |
| 4177 | } | ||
| 4178 | |||
| 4179 | #ifdef WITH_WSREP | ||
| 4180 |
6/10✓ Branch 0 taken 9959 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 9918 times.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 41 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 9959 times.
|
10000 | if (WSREP(thd) && |
| 4181 |
2/4✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 41 times.
|
41 | wsrep_to_isolation_begin(thd, NULL, NULL, first_table)) { |
| 4182 | ✗ | goto error; | |
| 4183 | } | ||
| 4184 | #endif /* WITH_WSREP */ | ||
| 4185 | |||
| 4186 |
3/4✓ Branch 0 taken 9915 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8337 times.
✓ Branch 3 taken 1578 times.
|
9959 | if (mysql_rename_tables(thd, first_table)) goto error; |
| 4187 | 1578 | break; | |
| 4188 | } | ||
| 4189 | 25623 | case SQLCOM_CHECKSUM: { | |
| 4190 | #ifdef WITH_WSREP | ||
| 4191 |
9/16✓ Branch 0 taken 25623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1679 times.
✓ Branch 3 taken 23944 times.
✓ Branch 4 taken 1679 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1679 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1679 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1679 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1679 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 25623 times.
|
25623 | WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ); |
| 4192 | #endif /* WITH_WSREP */ | ||
| 4193 |
2/4✓ Branch 0 taken 25623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25623 times.
✗ Branch 3 not taken.
|
25623 | assert(first_table == all_tables && first_table != nullptr); |
| 4194 |
3/4✓ Branch 0 taken 25623 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 25621 times.
|
25623 | if (check_table_access(thd, SELECT_ACL, all_tables, false, UINT_MAX, |
| 4195 | false)) | ||
| 4196 | 2 | goto error; /* purecov: inspected */ | |
| 4197 | |||
| 4198 |
1/2✓ Branch 0 taken 25621 times.
✗ Branch 1 not taken.
|
25621 | res = mysql_checksum_table(thd, first_table, &lex->check_opt); |
| 4199 | 25621 | break; | |
| 4200 | } | ||
| 4201 | 7894225 | case SQLCOM_REPLACE: | |
| 4202 | case SQLCOM_INSERT: | ||
| 4203 | case SQLCOM_REPLACE_SELECT: | ||
| 4204 | case SQLCOM_INSERT_SELECT: | ||
| 4205 | #ifdef WITH_WSREP | ||
| 4206 | { | ||
| 4207 |
13/16✓ Branch 0 taken 7894222 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1900471 times.
✓ Branch 3 taken 5993751 times.
✓ Branch 4 taken 31599 times.
✓ Branch 5 taken 1868872 times.
✓ Branch 6 taken 19858 times.
✓ Branch 7 taken 11741 times.
✓ Branch 8 taken 19813 times.
✓ Branch 9 taken 45 times.
✓ Branch 10 taken 19793 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 19793 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 7894205 times.
|
7894225 | WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE); |
| 4208 |
2/4✓ Branch 0 taken 7894297 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7894491 times.
✗ Branch 3 not taken.
|
7894205 | assert(first_table == all_tables && first_table != 0); |
| 4209 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7894491 times.
|
7894491 | assert(lex->m_sql_cmd != NULL); |
| 4210 |
1/2✓ Branch 0 taken 7895110 times.
✗ Branch 1 not taken.
|
7894491 | res = lex->m_sql_cmd->execute(thd); |
| 4211 | 7895110 | break; | |
| 4212 | } | ||
| 4213 | #endif /* WITH_WSREP */ | ||
| 4214 | 352708 | case SQLCOM_DELETE: | |
| 4215 | case SQLCOM_DELETE_MULTI: | ||
| 4216 | case SQLCOM_UPDATE: | ||
| 4217 | case SQLCOM_UPDATE_MULTI: | ||
| 4218 | #ifdef WITH_WSREP | ||
| 4219 | { | ||
| 4220 |
13/16✓ Branch 0 taken 352705 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 24830 times.
✓ Branch 3 taken 327875 times.
✓ Branch 4 taken 16456 times.
✓ Branch 5 taken 8374 times.
✓ Branch 6 taken 10870 times.
✓ Branch 7 taken 5586 times.
✓ Branch 8 taken 10868 times.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 10868 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 10868 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 352708 times.
|
352708 | WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE); |
| 4221 |
3/4✓ Branch 0 taken 352707 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 352716 times.
✗ Branch 3 not taken.
|
352708 | assert(first_table == all_tables && first_table != 0); |
| 4222 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 352716 times.
|
352716 | assert(lex->m_sql_cmd != NULL); |
| 4223 |
1/2✓ Branch 0 taken 352787 times.
✗ Branch 1 not taken.
|
352716 | res = lex->m_sql_cmd->execute(thd); |
| 4224 | 352787 | break; | |
| 4225 | } | ||
| 4226 | #endif /* WITH_WSREP */ | ||
| 4227 | 678214 | case SQLCOM_CREATE_TABLE: | |
| 4228 | case SQLCOM_CREATE_INDEX: | ||
| 4229 | case SQLCOM_DROP_INDEX: | ||
| 4230 | case SQLCOM_ASSIGN_TO_KEYCACHE: | ||
| 4231 | case SQLCOM_PRELOAD_KEYS: | ||
| 4232 | case SQLCOM_LOAD: { | ||
| 4233 |
2/4✓ Branch 0 taken 678214 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 678214 times.
✗ Branch 3 not taken.
|
678214 | assert(first_table == all_tables && first_table != nullptr); |
| 4234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 678214 times.
|
678214 | assert(lex->m_sql_cmd != nullptr); |
| 4235 |
1/2✓ Branch 0 taken 678177 times.
✗ Branch 1 not taken.
|
678214 | res = lex->m_sql_cmd->execute(thd); |
| 4236 | 678177 | break; | |
| 4237 | } | ||
| 4238 | 160725 | case SQLCOM_DROP_TABLE: { | |
| 4239 |
2/4✓ Branch 0 taken 160725 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 160725 times.
✗ Branch 3 not taken.
|
160725 | assert(first_table == all_tables && first_table != nullptr); |
| 4240 |
2/2✓ Branch 0 taken 153464 times.
✓ Branch 1 taken 7261 times.
|
160725 | if (!lex->drop_temporary) { |
| 4241 |
3/4✓ Branch 0 taken 153464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 153455 times.
|
153464 | if (check_table_access(thd, DROP_ACL, all_tables, false, UINT_MAX, |
| 4242 | false)) | ||
| 4243 | 9 | goto error; /* purecov: inspected */ | |
| 4244 | } | ||
| 4245 | |||
| 4246 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 160692 times.
|
160716 | if (thd->variables.binlog_ddl_skip_rewrite) { |
| 4247 | 24 | size_t table_count = 0; | |
| 4248 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 18 times.
|
48 | for (TABLE_LIST *table = all_tables; table; table = table->next_local) { |
| 4249 | 30 | ++table_count; | |
| 4250 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
|
30 | if (table_count > 1) { |
| 4251 | /* | ||
| 4252 | When 'binlog_ddl_skip_rewrite' option is enabled, logging query | ||
| 4253 | without rewrite does not not work as expected if tables contain | ||
| 4254 | both normal tables and temporary tables,consider these two cases. | ||
| 4255 | Case1: Statements like 'drop table t1,t2' where t1 is a normal | ||
| 4256 | table and t2 is a temporary table, will fail on the slave because | ||
| 4257 | temporary table will not be present on the slave. | ||
| 4258 | Case2: Statements like 'DROP TABLE t1 / *!80024 ,t2 * /' will | ||
| 4259 | generate single table or multi table drop statements depending | ||
| 4260 | on the mysql version. | ||
| 4261 | */ | ||
| 4262 | |||
| 4263 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | my_error(ER_DROP_MULTI_TABLE, MYF(0), "binlog_ddl_skip_rewrite"); |
| 4264 | 6 | goto error; | |
| 4265 | } | ||
| 4266 | } | ||
| 4267 | } | ||
| 4268 | |||
| 4269 | #ifdef WITH_WSREP | ||
| 4270 |
2/2✓ Branch 0 taken 161185 times.
✓ Branch 1 taken 37764 times.
|
198949 | for (TABLE_LIST *table = all_tables; table; table = table->next_global) { |
| 4271 |
6/6✓ Branch 0 taken 153509 times.
✓ Branch 1 taken 7676 times.
✓ Branch 2 taken 134291 times.
✓ Branch 3 taken 19218 times.
✓ Branch 4 taken 122946 times.
✓ Branch 5 taken 38239 times.
|
448985 | if (!lex->drop_temporary && |
| 4272 | 153509 | (!thd->is_current_stmt_binlog_format_row() || | |
| 4273 |
3/4✓ Branch 0 taken 134291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103728 times.
✓ Branch 3 taken 30563 times.
|
134291 | !find_temporary_table(thd, table))) { |
| 4274 | 122946 | wsrep::key_array keys; | |
| 4275 |
3/4✓ Branch 0 taken 122946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 122944 times.
|
122946 | if (wsrep_append_fk_parent_table(thd, all_tables, &keys)) { |
| 4276 | 2 | return true; | |
| 4277 | } | ||
| 4278 |
11/16✓ Branch 0 taken 122944 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17497 times.
✓ Branch 3 taken 105447 times.
✓ Branch 4 taken 3663 times.
✓ Branch 5 taken 13834 times.
✓ Branch 6 taken 3661 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 3661 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3661 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 3661 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 122944 times.
|
122944 | WSREP_TO_ISOLATION_BEGIN_FK_TABLES_IF(NULL, NULL, all_tables, &keys) { |
| 4279 | ✗ | goto error; | |
| 4280 | } | ||
| 4281 | 122944 | break; | |
| 4282 |
2/3✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 122944 times.
|
122946 | } |
| 4283 | } | ||
| 4284 | #endif /* WITH_WSREP */ | ||
| 4285 | |||
| 4286 | /* DDL and binlog write order are protected by metadata locks. */ | ||
| 4287 | 321392 | res = mysql_rm_table(thd, first_table, lex->drop_if_exists, | |
| 4288 |
1/2✓ Branch 0 taken 160684 times.
✗ Branch 1 not taken.
|
160708 | lex->drop_temporary); |
| 4289 | /* when dropping temporary tables if @@session_track_state_change is ON | ||
| 4290 | then send the boolean tracker in the OK packet */ | ||
| 4291 |
4/4✓ Branch 0 taken 156712 times.
✓ Branch 1 taken 3972 times.
✓ Branch 2 taken 7167 times.
✓ Branch 3 taken 149545 times.
|
160684 | if (!res && lex->drop_temporary) { |
| 4292 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7160 times.
|
7167 | if (thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER) |
| 4293 |
1/2✓ Branch 0 taken 7167 times.
✗ Branch 1 not taken.
|
7167 | ->is_enabled()) |
| 4294 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | thd->session_tracker.get_tracker(SESSION_STATE_CHANGE_TRACKER) |
| 4295 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | ->mark_as_changed(thd, {}); |
| 4296 | } | ||
| 4297 | 160684 | } break; | |
| 4298 | 89892 | case SQLCOM_CHANGE_DB: { | |
| 4299 | 89892 | const LEX_CSTRING db_str = {query_block->db, strlen(query_block->db)}; | |
| 4300 | |||
| 4301 |
4/6✓ Branch 0 taken 89892 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 89867 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 89867 times.
✗ Branch 5 not taken.
|
89892 | if (!mysql_change_db(thd, db_str, false)) my_ok(thd); |
| 4302 | |||
| 4303 | 89892 | break; | |
| 4304 | } | ||
| 4305 | |||
| 4306 | 1504619 | case SQLCOM_SET_OPTION: { | |
| 4307 | 1504619 | List<set_var_base> *lex_var_list = &lex->var_list; | |
| 4308 | |||
| 4309 | #ifdef WITH_WSREP | ||
| 4310 | 1504619 | ulong cached_pxc_maint_mode = pxc_maint_mode; | |
| 4311 | |||
| 4312 | 1504619 | ulong cached_osu_method = WSREP_OSU_NONE; | |
| 4313 |
6/8✓ Branch 0 taken 39905 times.
✓ Branch 1 taken 1464714 times.
✓ Branch 2 taken 39905 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39905 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39905 times.
✓ Branch 7 taken 1464714 times.
|
1504619 | if (thd->variables.wsrep_on && wsrep_thd_is_local(thd)) { |
| 4314 | 39905 | cached_osu_method = thd->variables.wsrep_OSU_method; | |
| 4315 | } | ||
| 4316 | #endif /* WITH_WSREP */ | ||
| 4317 | |||
| 4318 |
3/4✓ Branch 0 taken 1504653 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1504650 times.
|
1504619 | if (check_table_access(thd, SELECT_ACL, all_tables, false, UINT_MAX, |
| 4319 | false)) | ||
| 4320 | 3 | goto error; | |
| 4321 | |||
| 4322 |
3/4✓ Branch 0 taken 1504587 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
✓ Branch 3 taken 1504471 times.
|
1504650 | if (open_tables_for_query(thd, all_tables, false)) goto error; |
| 4323 |
2/2✓ Branch 0 taken 509647 times.
✓ Branch 1 taken 994852 times.
|
1504471 | if (!thd->stmt_arena->is_regular()) { |
| 4324 |
1/2✓ Branch 0 taken 509664 times.
✗ Branch 1 not taken.
|
509647 | lex->restore_cmd_properties(); |
| 4325 |
1/2✓ Branch 0 taken 509677 times.
✗ Branch 1 not taken.
|
509664 | bind_fields(thd->stmt_arena->item_list()); |
| 4326 | 509808 | if (all_tables != nullptr && | |
| 4327 |
6/6✓ Branch 0 taken 130 times.
✓ Branch 1 taken 509547 times.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 509677 times.
|
509784 | !thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute() && |
| 4328 |
3/4✓ Branch 0 taken 107 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 106 times.
|
106 | query_block->check_privileges_for_subqueries(thd)) |
| 4329 | 1 | return true; | |
| 4330 | } | ||
| 4331 |
3/4✓ Branch 0 taken 1504134 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1497712 times.
✓ Branch 3 taken 6422 times.
|
1504529 | if (!(res = sql_set_variables(thd, lex_var_list, true))) |
| 4332 |
1/2✓ Branch 0 taken 1497923 times.
✗ Branch 1 not taken.
|
1497712 | my_ok(thd); |
| 4333 | else { | ||
| 4334 | /* | ||
| 4335 | We encountered some sort of error, but no message was sent. | ||
| 4336 | Send something semi-generic here since we don't know which | ||
| 4337 | assignment in the list caused the error. | ||
| 4338 | */ | ||
| 4339 |
4/6✓ Branch 0 taken 6445 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6443 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
6422 | if (!thd->is_error()) my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET"); |
| 4340 | 6445 | goto error; | |
| 4341 | } | ||
| 4342 | |||
| 4343 | #ifdef WITH_WSREP | ||
| 4344 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1497919 times.
|
1497923 | if (cached_pxc_maint_mode != pxc_maint_mode && |
| 4345 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | pxc_maint_mode == PXC_MAINT_MODE_MAINTENANCE) { |
| 4346 |
10/22✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
|
2 | WSREP_INFO("Sleep for %lu secs while switching to maintenance mode", |
| 4347 | pxc_maint_transition_period); | ||
| 4348 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
2 | sleep(pxc_maint_transition_period); |
| 4349 | } | ||
| 4350 | |||
| 4351 |
6/8✓ Branch 0 taken 63031 times.
✓ Branch 1 taken 1434691 times.
✓ Branch 2 taken 63031 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63031 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 63031 times.
✓ Branch 7 taken 1434691 times.
|
1497722 | if (thd->variables.wsrep_on && wsrep_thd_is_local(thd)) { |
| 4352 | 63031 | ulong osu_method = thd->variables.wsrep_OSU_method; | |
| 4353 | /* OSU method set to RSU. | ||
| 4354 | Commit/Rollback existing transaction (if any) */ | ||
| 4355 |
4/4✓ Branch 0 taken 36998 times.
✓ Branch 1 taken 26033 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 36978 times.
|
63031 | if (cached_osu_method == WSREP_OSU_TOI && osu_method == WSREP_OSU_RSU) { |
| 4356 |
2/4✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
|
20 | if (trans_commit_implicit(thd)) { |
| 4357 | ✗ | thd->mdl_context.release_transactional_locks(); | |
| 4358 | ✗ | WSREP_DEBUG( | |
| 4359 | "Transaction implicit commit failed" | ||
| 4360 | " MDL released: %u", | ||
| 4361 | thd->thread_id()); | ||
| 4362 | ✗ | return -1; | |
| 4363 | } | ||
| 4364 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | thd->mdl_context.release_transactional_locks(); |
| 4365 |
5/10✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 20 times.
|
20 | if (wsrep_thd_is_local(thd) && wsrep_after_statement(thd)) { |
| 4366 | ✗ | return -1; | |
| 4367 | } | ||
| 4368 | } | ||
| 4369 | } | ||
| 4370 | #endif /* WITH_WSREP */ | ||
| 4371 | |||
| 4372 | #ifndef NDEBUG | ||
| 4373 | /* | ||
| 4374 | Makes server crash when executing SET SESSION debug = 'd,crash_now'; | ||
| 4375 | See mysql-test/include/dbug_crash[_all].inc | ||
| 4376 | */ | ||
| 4377 | 1497722 | const bool force_server_crash_dbug = false; | |
| 4378 |
2/4✓ Branch 0 taken 1497628 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1497628 times.
|
1497722 | DBUG_EXECUTE_IF("crash_now", assert(force_server_crash_dbug);); |
| 4379 |
4/6✓ Branch 0 taken 1497751 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1497736 times.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
|
1497628 | DBUG_EXECUTE_IF("crash_now_safe", DBUG_SUICIDE();); |
| 4380 | #endif | ||
| 4381 | |||
| 4382 | 1497736 | break; | |
| 4383 | } | ||
| 4384 | 922 | case SQLCOM_SET_PASSWORD: { | |
| 4385 | 922 | List<set_var_base> *lex_var_list = &lex->var_list; | |
| 4386 | |||
| 4387 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
|
922 | assert(lex_var_list->elements == 1); |
| 4388 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
|
922 | assert(all_tables == nullptr); |
| 4389 | 922 | Userhostpassword_list generated_passwords; | |
| 4390 |
3/4✓ Branch 0 taken 920 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 688 times.
✓ Branch 3 taken 232 times.
|
922 | if (!(res = sql_set_variables(thd, lex_var_list, false))) { |
| 4391 |
1/2✓ Branch 0 taken 688 times.
✗ Branch 1 not taken.
|
688 | List_iterator_fast<set_var_base> it(*lex_var_list); |
| 4392 | set_var_base *var; | ||
| 4393 |
2/2✓ Branch 0 taken 688 times.
✓ Branch 1 taken 688 times.
|
1376 | while ((var = it++)) { |
| 4394 | 688 | set_var_password *setpasswd = static_cast<set_var_password *>(var); | |
| 4395 |
2/2✓ Branch 0 taken 53 times.
✓ Branch 1 taken 635 times.
|
688 | if (setpasswd->has_generated_password()) { |
| 4396 | 53 | const LEX_USER *user = setpasswd->get_user(); | |
| 4397 | 53 | random_password_info p{ | |
| 4398 | 53 | std::string(user->user.str, user->user.length), | |
| 4399 | 53 | std::string(user->host.str, user->host.length), | |
| 4400 |
3/6✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
|
53 | setpasswd->get_generated_password(), 1}; |
| 4401 |
1/2✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
|
53 | generated_passwords.push_back(p); |
| 4402 | 53 | } | |
| 4403 | } | ||
| 4404 |
2/2✓ Branch 0 taken 53 times.
✓ Branch 1 taken 635 times.
|
688 | if (generated_passwords.size() > 0) { |
| 4405 |
2/4✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
|
53 | if (send_password_result_set(thd, generated_passwords)) goto error; |
| 4406 | } // end if generated_passwords | ||
| 4407 |
3/4✓ Branch 0 taken 635 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 635 times.
✗ Branch 3 not taken.
|
688 | if (generated_passwords.size() == 0) my_ok(thd); |
| 4408 | } else { | ||
| 4409 | // We encountered some sort of error, but no message was sent. | ||
| 4410 |
2/4✓ Branch 0 taken 232 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 232 times.
|
232 | if (!thd->is_error()) |
| 4411 | ✗ | my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET PASSWORD"); | |
| 4412 | 232 | goto error; | |
| 4413 | } | ||
| 4414 | |||
| 4415 | 688 | break; | |
| 4416 |
2/2✓ Branch 0 taken 232 times.
✓ Branch 1 taken 688 times.
|
920 | } |
| 4417 | |||
| 4418 | 4453 | case SQLCOM_UNLOCK_TABLES: { | |
| 4419 | #ifdef WITH_WSREP | ||
| 4420 | /* UNLOCK Tables is generic statement and not all lock table variants | ||
| 4421 | are blocked (only one with explict table lock are blocked). */ | ||
| 4422 | 4453 | bool table_lock = (thd->variables.option_bits & OPTION_TABLE_LOCK); | |
| 4423 | #endif /* WITH_WSREP */ | ||
| 4424 | |||
| 4425 | /* | ||
| 4426 | It is critical for mysqldump --single-transaction --source-data that | ||
| 4427 | UNLOCK TABLES does not implicitly commit a connection which has only | ||
| 4428 | done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes | ||
| 4429 | false, mysqldump will not work. | ||
| 4430 | */ | ||
| 4431 |
2/2✓ Branch 0 taken 2873 times.
✓ Branch 1 taken 1580 times.
|
4453 | if (thd->variables.option_bits & OPTION_TABLE_LOCK) { |
| 4432 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2873 times.
|
2873 | assert(!thd->backup_tables_lock.is_acquired()); |
| 4433 | /* | ||
| 4434 | Can we commit safely? If not, return to avoid releasing | ||
| 4435 | transactional metadata locks. | ||
| 4436 | */ | ||
| 4437 |
2/4✓ Branch 0 taken 2873 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2873 times.
|
2873 | if (trans_check_state(thd)) return -1; |
| 4438 |
1/2✓ Branch 0 taken 2873 times.
✗ Branch 1 not taken.
|
2873 | res = trans_commit_implicit(thd); |
| 4439 |
1/2✓ Branch 0 taken 2873 times.
✗ Branch 1 not taken.
|
2873 | thd->locked_tables_list.unlock_locked_tables(thd); |
| 4440 |
1/2✓ Branch 0 taken 2873 times.
✗ Branch 1 not taken.
|
2873 | thd->mdl_context.release_transactional_locks(); |
| 4441 | 2873 | thd->variables.option_bits &= ~(OPTION_TABLE_LOCK); | |
| 4442 | } | ||
| 4443 | |||
| 4444 |
2/2✓ Branch 0 taken 252 times.
✓ Branch 1 taken 4201 times.
|
4453 | if (thd->backup_tables_lock.is_acquired()) { |
| 4445 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 252 times.
|
252 | assert(!(thd->variables.option_bits & OPTION_TABLE_LOCK)); |
| 4446 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 252 times.
|
252 | assert(!thd->global_read_lock.is_acquired()); |
| 4447 | |||
| 4448 | 252 | thd->backup_tables_lock.release(thd); | |
| 4449 | } | ||
| 4450 | |||
| 4451 |
2/2✓ Branch 0 taken 584 times.
✓ Branch 1 taken 3869 times.
|
4453 | if (thd->global_read_lock.is_acquired()) |
| 4452 |
1/2✓ Branch 0 taken 584 times.
✗ Branch 1 not taken.
|
584 | thd->global_read_lock.unlock_global_read_lock(thd); |
| 4453 | |||
| 4454 | #ifdef WITH_WSREP | ||
| 4455 | /* | ||
| 4456 | This is for resuming the provider when used for | ||
| 4457 | FLUSH TABLES <table> WITH READ LOCK or | ||
| 4458 | FLUSH TABLES <table> FOR EXPORT. | ||
| 4459 | Note, the return value for resume is ignored here because | ||
| 4460 | we don't want to fail the query if provider is already resumed. | ||
| 4461 | |||
| 4462 | Also, note that this is done after GRL is unlocked. | ||
| 4463 | This is important because provider is resumed there | ||
| 4464 | and we don't want do it again. | ||
| 4465 | */ | ||
| 4466 |
9/12✓ Branch 0 taken 4453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 370 times.
✓ Branch 3 taken 4083 times.
✓ Branch 4 taken 370 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 364 times.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 86 times.
✓ Branch 9 taken 278 times.
✓ Branch 10 taken 86 times.
✗ Branch 11 not taken.
|
4453 | if (WSREP(thd) && table_lock) thd->global_read_lock.wsrep_resume_once(); |
| 4467 | #endif /* WITH_WSREP */ | ||
| 4468 | |||
| 4469 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4452 times.
|
4453 | if (res) goto error; |
| 4470 |
1/2✓ Branch 0 taken 4452 times.
✗ Branch 1 not taken.
|
4452 | my_ok(thd); |
| 4471 | 4452 | break; | |
| 4472 | } | ||
| 4473 | |||
| 4474 | 2867 | case SQLCOM_LOCK_TABLES: | |
| 4475 | |||
| 4476 | #ifdef WITH_WSREP | ||
| 4477 |
3/4✓ Branch 0 taken 2867 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2865 times.
|
2867 | if (pxc_strict_mode_lock_check(thd)) goto error; |
| 4478 | #endif /* WITH_WSREP */ | ||
| 4479 | |||
| 4480 | /* | ||
| 4481 | Do not allow LOCK TABLES under an active LOCK TABLES FOR BACKUP in the | ||
| 4482 | same connection. | ||
| 4483 | */ | ||
| 4484 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2865 times.
|
2865 | if (thd->backup_tables_lock.abort_if_acquired()) goto error; |
| 4485 | |||
| 4486 | /* | ||
| 4487 | Can we commit safely? If not, return to avoid releasing | ||
| 4488 | transactional metadata locks. | ||
| 4489 | */ | ||
| 4490 |
2/4✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2865 times.
|
2865 | if (trans_check_state(thd)) return -1; |
| 4491 | /* We must end the transaction first, regardless of anything */ | ||
| 4492 |
1/2✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
|
2865 | res = trans_commit_implicit(thd); |
| 4493 |
1/2✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
|
2865 | thd->locked_tables_list.unlock_locked_tables(thd); |
| 4494 | /* Release transactional metadata locks. */ | ||
| 4495 |
1/2✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
|
2865 | thd->mdl_context.release_transactional_locks(); |
| 4496 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2865 times.
|
2865 | if (res) goto error; |
| 4497 | |||
| 4498 | /* | ||
| 4499 | Here we have to pre-open temporary tables for LOCK TABLES. | ||
| 4500 | |||
| 4501 | CF_PREOPEN_TMP_TABLES is not set for this SQL statement simply | ||
| 4502 | because LOCK TABLES calls close_thread_tables() as a first thing | ||
| 4503 | (it's called from unlock_locked_tables() above). So even if | ||
| 4504 | CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened | ||
| 4505 | in a usual way, they would have been closed. | ||
| 4506 | */ | ||
| 4507 | |||
| 4508 |
3/4✓ Branch 0 taken 2865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2864 times.
|
2865 | if (open_temporary_tables(thd, all_tables)) goto error; |
| 4509 | |||
| 4510 |
3/4✓ Branch 0 taken 2864 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 245 times.
✓ Branch 3 taken 2619 times.
|
2864 | if (lock_tables_precheck(thd, all_tables)) goto error; |
| 4511 | |||
| 4512 | 2619 | thd->variables.option_bits |= OPTION_TABLE_LOCK; | |
| 4513 | |||
| 4514 |
1/2✓ Branch 0 taken 2619 times.
✗ Branch 1 not taken.
|
2619 | res = lock_tables_open_and_lock_tables(thd, all_tables); |
| 4515 | |||
| 4516 |
2/2✓ Branch 0 taken 55 times.
✓ Branch 1 taken 2564 times.
|
2619 | if (res) { |
| 4517 | 55 | thd->variables.option_bits &= ~(OPTION_TABLE_LOCK); | |
| 4518 | } else { | ||
| 4519 |
1/2✓ Branch 0 taken 2564 times.
✗ Branch 1 not taken.
|
2564 | my_ok(thd); |
| 4520 | } | ||
| 4521 | 2619 | break; | |
| 4522 | |||
| 4523 | 35 | case SQLCOM_IMPORT: | |
| 4524 |
1/2✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
|
35 | res = lex->m_sql_cmd->execute(thd); |
| 4525 | 35 | break; | |
| 4526 | |||
| 4527 | 254 | case SQLCOM_LOCK_TABLES_FOR_BACKUP: | |
| 4528 |
3/6✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 254 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 254 times.
✗ Branch 5 not taken.
|
254 | if (!lock_tables_for_backup(thd)) my_ok(thd); |
| 4529 | |||
| 4530 | 254 | break; | |
| 4531 | 79 | case SQLCOM_CREATE_COMPRESSION_DICTIONARY: { | |
| 4532 | #ifdef WITH_WSREP | ||
| 4533 |
8/14✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 75 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 79 times.
|
79 | WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) |
| 4534 | #endif /* WITH_WSREP */ | ||
| 4535 | |||
| 4536 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 58 times.
|
79 | if (lex->create_info->zip_dict_name->fixed == 0) |
| 4537 |
1/2✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
|
21 | lex->create_info->zip_dict_name->fix_fields(thd, 0); |
| 4538 | 79 | String dict_data; | |
| 4539 | String *dict_data_ptr = | ||
| 4540 |
1/2✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
|
79 | lex->create_info->zip_dict_name->val_str_ascii(&dict_data); |
| 4541 |
3/6✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 79 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 79 times.
|
79 | if (dict_data_ptr == nullptr || dict_data_ptr->ptr() == nullptr) { |
| 4542 | ✗ | dict_data.set("", 0, &my_charset_bin); | |
| 4543 | ✗ | dict_data_ptr = &dict_data; | |
| 4544 | } | ||
| 4545 | |||
| 4546 | 237 | if ((res = compression_dict::create_zip_dict( | |
| 4547 |
1/2✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
|
79 | thd, lex->ident.str, lex->ident.length, dict_data_ptr->ptr(), |
| 4548 | dict_data_ptr->length(), | ||
| 4549 | 79 | (lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) != 0, | |
| 4550 |
2/2✓ Branch 0 taken 71 times.
✓ Branch 1 taken 8 times.
|
79 | false)) == 0) |
| 4551 |
1/2✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
|
71 | my_ok(thd); |
| 4552 | 79 | break; | |
| 4553 | 79 | } | |
| 4554 | 90 | case SQLCOM_DROP_COMPRESSION_DICTIONARY: { | |
| 4555 | #ifdef WITH_WSREP | ||
| 4556 |
8/14✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 86 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 90 times.
|
90 | WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) |
| 4557 | #endif /* WITH_WSREP */ | ||
| 4558 | |||
| 4559 | 180 | if ((res = compression_dict::drop_zip_dict( | |
| 4560 |
3/4✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✓ Branch 3 taken 14 times.
|
90 | thd, lex->ident.str, lex->ident.length, lex->drop_if_exists)) == |
| 4561 | 0) | ||
| 4562 |
1/2✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
|
76 | my_ok(thd); |
| 4563 | 90 | break; | |
| 4564 | } | ||
| 4565 | 15607 | case SQLCOM_CREATE_DB: { | |
| 4566 | const char *alias; | ||
| 4567 |
4/6✓ Branch 0 taken 15607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15607 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 15602 times.
|
31214 | if (!(alias = thd->strmake(lex->name.str, lex->name.length)) || |
| 4568 |
3/4✓ Branch 0 taken 15607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 15602 times.
|
15607 | (check_and_convert_db_name(&lex->name, false) != |
| 4569 | Ident_name_check::OK)) | ||
| 4570 | 15603 | break; | |
| 4571 |
3/4✓ Branch 0 taken 15602 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 15591 times.
|
15602 | if (check_access(thd, CREATE_ACL, lex->name.str, nullptr, nullptr, true, |
| 4572 | false)) | ||
| 4573 | 11 | break; | |
| 4574 | |||
| 4575 | #ifdef WITH_WSREP | ||
| 4576 |
10/14✓ Branch 0 taken 15591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9902 times.
✓ Branch 3 taken 5689 times.
✓ Branch 4 taken 606 times.
✓ Branch 5 taken 9296 times.
✓ Branch 6 taken 153 times.
✓ Branch 7 taken 453 times.
✓ Branch 8 taken 153 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 153 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 15591 times.
|
15591 | WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL) |
| 4577 | #endif /* WITH_WSREP */ | ||
| 4578 | /* | ||
| 4579 | As mysql_create_db() may modify HA_CREATE_INFO structure passed to | ||
| 4580 | it, we need to use a copy of LEX::create_info to make execution | ||
| 4581 | prepared statement- safe. | ||
| 4582 | */ | ||
| 4583 |
1/2✓ Branch 0 taken 15591 times.
✗ Branch 1 not taken.
|
15591 | HA_CREATE_INFO create_info(*lex->create_info); |
| 4584 |
1/2✓ Branch 0 taken 15586 times.
✗ Branch 1 not taken.
|
15591 | res = mysql_create_db( |
| 4585 |
1/2✓ Branch 0 taken 15591 times.
✗ Branch 1 not taken.
|
15591 | thd, (lower_case_table_names == 2 ? alias : lex->name.str), |
| 4586 | &create_info); | ||
| 4587 | 15586 | break; | |
| 4588 | 15586 | } | |
| 4589 | 6136 | case SQLCOM_DROP_DB: { | |
| 4590 |
3/4✓ Branch 0 taken 6136 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6134 times.
|
6136 | if (check_and_convert_db_name(&lex->name, false) != Ident_name_check::OK) |
| 4591 | 2 | break; | |
| 4592 |
3/4✓ Branch 0 taken 6134 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 6120 times.
|
6134 | if (check_access(thd, DROP_ACL, lex->name.str, nullptr, nullptr, true, |
| 4593 | false)) | ||
| 4594 | 14 | break; | |
| 4595 | #ifdef WITH_WSREP | ||
| 4596 |
9/14✓ Branch 0 taken 6120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 244 times.
✓ Branch 3 taken 5876 times.
✓ Branch 4 taken 145 times.
✓ Branch 5 taken 99 times.
✓ Branch 6 taken 145 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 145 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 145 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6120 times.
|
6120 | WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL) |
| 4597 | #endif /* WITH_WSREP */ | ||
| 4598 |
1/2✓ Branch 0 taken 6117 times.
✗ Branch 1 not taken.
|
6120 | res = mysql_rm_db(thd, to_lex_cstring(lex->name), lex->drop_if_exists); |
| 4599 | 6117 | break; | |
| 4600 | } | ||
| 4601 | 975 | case SQLCOM_ALTER_DB: { | |
| 4602 |
3/4✓ Branch 0 taken 975 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 973 times.
|
975 | if (check_and_convert_db_name(&lex->name, false) != Ident_name_check::OK) |
| 4603 | 972 | break; | |
| 4604 |
3/4✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 968 times.
|
973 | if (check_access(thd, ALTER_ACL, lex->name.str, nullptr, nullptr, true, |
| 4605 | false)) | ||
| 4606 | 5 | break; | |
| 4607 | #ifdef WITH_WSREP | ||
| 4608 |
9/14✓ Branch 0 taken 968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 211 times.
✓ Branch 3 taken 757 times.
✓ Branch 4 taken 26 times.
✓ Branch 5 taken 185 times.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 26 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 26 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 968 times.
|
968 | WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL) |
| 4609 | #endif /* WITH_WSREP */ | ||
| 4610 | /* | ||
| 4611 | As mysql_alter_db() may modify HA_CREATE_INFO structure passed to | ||
| 4612 | it, we need to use a copy of LEX::create_info to make execution | ||
| 4613 | prepared statement- safe. | ||
| 4614 | */ | ||
| 4615 |
1/2✓ Branch 0 taken 968 times.
✗ Branch 1 not taken.
|
968 | HA_CREATE_INFO create_info(*lex->create_info); |
| 4616 |
1/2✓ Branch 0 taken 965 times.
✗ Branch 1 not taken.
|
968 | res = mysql_alter_db(thd, lex->name.str, &create_info); |
| 4617 | 965 | break; | |
| 4618 | 965 | } | |
| 4619 | 1142 | case SQLCOM_CREATE_EVENT: | |
| 4620 | case SQLCOM_ALTER_EVENT: | ||
| 4621 | do { | ||
| 4622 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1142 times.
|
1142 | assert(lex->event_parse_data); |
| 4623 |
3/4✓ Branch 0 taken 1142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1134 times.
|
1142 | if (lex->table_or_sp_used()) { |
| 4624 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | my_error(ER_NOT_SUPPORTED_YET, MYF(0), |
| 4625 | "Usage of subqueries or stored " | ||
| 4626 | "function calls as part of this statement"); | ||
| 4627 | 8 | break; | |
| 4628 | } | ||
| 4629 | |||
| 4630 |
1/2✓ Branch 0 taken 1134 times.
✗ Branch 1 not taken.
|
1134 | res = sp_process_definer(thd); |
| 4631 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1131 times.
|
1134 | if (res) break; |
| 4632 | |||
| 4633 |
2/3✓ Branch 0 taken 930 times.
✓ Branch 1 taken 201 times.
✗ Branch 2 not taken.
|
1131 | switch (lex->sql_command) { |
| 4634 | 930 | case SQLCOM_CREATE_EVENT: { | |
| 4635 | 930 | bool if_not_exists = | |
| 4636 | 930 | (lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS); | |
| 4637 | 924 | res = | |
| 4638 |
1/2✓ Branch 0 taken 924 times.
✗ Branch 1 not taken.
|
930 | Events::create_event(thd, lex->event_parse_data, if_not_exists); |
| 4639 | 924 | break; | |
| 4640 | } | ||
| 4641 | 201 | case SQLCOM_ALTER_EVENT: { | |
| 4642 | 201 | LEX_CSTRING name_lex_str = NULL_CSTR; | |
| 4643 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 170 times.
|
201 | if (lex->spname) { |
| 4644 | 31 | name_lex_str.str = lex->spname->m_name.str; | |
| 4645 | 31 | name_lex_str.length = lex->spname->m_name.length; | |
| 4646 | } | ||
| 4647 | |||
| 4648 | 195 | res = | |
| 4649 |
1/2✓ Branch 0 taken 195 times.
✗ Branch 1 not taken.
|
402 | Events::update_event(thd, lex->event_parse_data, |
| 4650 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 170 times.
|
201 | lex->spname ? &lex->spname->m_db : nullptr, |
| 4651 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 170 times.
|
201 | lex->spname ? &name_lex_str : nullptr); |
| 4652 | 195 | break; | |
| 4653 | } | ||
| 4654 | ✗ | default: | |
| 4655 | ✗ | assert(0); | |
| 4656 | } | ||
| 4657 |
3/8✓ Branch 0 taken 1119 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1119 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1119 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
1119 | DBUG_PRINT("info", ("DDL error code=%d", res)); |
| 4658 |
7/8✓ Branch 0 taken 1039 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 1032 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 1032 times.
✓ Branch 5 taken 87 times.
✓ Branch 6 taken 1032 times.
✗ Branch 7 not taken.
|
1119 | if (!res && !thd->killed) my_ok(thd); |
| 4659 | |||
| 4660 | } while (false); | ||
| 4661 | /* Don't do it, if we are inside a SP */ | ||
| 4662 |
2/2✓ Branch 0 taken 1109 times.
✓ Branch 1 taken 21 times.
|
1130 | if (!thd->sp_runtime_ctx) { |
| 4663 |
1/2✓ Branch 0 taken 1109 times.
✗ Branch 1 not taken.
|
1109 | sp_head::destroy(lex->sphead); |
| 4664 | 1109 | lex->sphead = nullptr; | |
| 4665 | } | ||
| 4666 | /* lex->cleanup() is called outside, no need to call it here */ | ||
| 4667 | 1130 | break; | |
| 4668 | 500 | case SQLCOM_DROP_EVENT: { | |
| 4669 |
3/4✓ Branch 0 taken 494 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 474 times.
✓ Branch 3 taken 20 times.
|
500 | if (!(res = Events::drop_event(thd, lex->spname->m_db, |
| 4670 | 500 | to_lex_cstring(lex->spname->m_name), | |
| 4671 | 500 | lex->drop_if_exists))) | |
| 4672 |
1/2✓ Branch 0 taken 474 times.
✗ Branch 1 not taken.
|
474 | my_ok(thd); |
| 4673 | 494 | break; | |
| 4674 | } | ||
| 4675 | 205 | case SQLCOM_CREATE_FUNCTION: // UDF function | |
| 4676 | { | ||
| 4677 |
3/4✓ Branch 0 taken 205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 204 times.
|
205 | if (check_access(thd, INSERT_ACL, "mysql", nullptr, nullptr, true, false)) |
| 4678 | 1 | break; | |
| 4679 | #ifdef WITH_WSREP | ||
| 4680 |
8/14✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 202 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 204 times.
|
204 | WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) |
| 4681 | #endif /* WITH_WSREP */ | ||
| 4682 |
2/2✓ Branch 0 taken 188 times.
✓ Branch 1 taken 10 times.
|
198 | if (!(res = mysql_create_function( |
| 4683 | thd, &lex->udf, | ||
| 4684 |
1/2✓ Branch 0 taken 198 times.
✗ Branch 1 not taken.
|
204 | lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS))) |
| 4685 |
1/2✓ Branch 0 taken 188 times.
✗ Branch 1 not taken.
|
188 | my_ok(thd); |
| 4686 | 198 | break; | |
| 4687 | } | ||
| 4688 | 6788 | case SQLCOM_CREATE_USER: { | |
| 4689 |
1/2✓ Branch 0 taken 6788 times.
✗ Branch 1 not taken.
|
6788 | if (check_access(thd, INSERT_ACL, "mysql", nullptr, nullptr, true, |
| 4690 |
4/4✓ Branch 0 taken 13 times.
✓ Branch 1 taken 6775 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6782 times.
|
6801 | true) && |
| 4691 |
3/4✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 7 times.
|
13 | check_global_access(thd, CREATE_USER_ACL)) |
| 4692 | 6 | break; | |
| 4693 | /* Conditionally writes to binlog */ | ||
| 4694 |
1/2✓ Branch 0 taken 6782 times.
✗ Branch 1 not taken.
|
6782 | HA_CREATE_INFO create_info(*lex->create_info); |
| 4695 | 6776 | if (!(res = mysql_create_user( | |
| 4696 | 6782 | thd, lex->users_list, | |
| 4697 |
1/2✓ Branch 0 taken 6776 times.
✗ Branch 1 not taken.
|
6782 | create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS, false))) { |
| 4698 | // OK or result set was already sent. | ||
| 4699 | } | ||
| 4700 | |||
| 4701 | 6776 | break; | |
| 4702 | 6776 | } | |
| 4703 | 5621 | case SQLCOM_DROP_USER: { | |
| 4704 |
1/2✓ Branch 0 taken 5621 times.
✗ Branch 1 not taken.
|
5621 | if (check_access(thd, DELETE_ACL, "mysql", nullptr, nullptr, true, |
| 4705 |
4/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 5610 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5617 times.
|
5632 | true) && |
| 4706 |
3/4✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 7 times.
|
11 | check_global_access(thd, CREATE_USER_ACL)) |
| 4707 | 4 | break; | |
| 4708 | /* Conditionally writes to binlog */ | ||
| 4709 |
3/4✓ Branch 0 taken 5609 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5405 times.
✓ Branch 3 taken 204 times.
|
5617 | if (!(res = mysql_drop_user(thd, lex->users_list, lex->drop_if_exists, |
| 4710 | false))) | ||
| 4711 |
1/2✓ Branch 0 taken 5405 times.
✗ Branch 1 not taken.
|
5405 | my_ok(thd); |
| 4712 | |||
| 4713 | 5609 | break; | |
| 4714 | } | ||
| 4715 | 523 | case SQLCOM_RENAME_USER: { | |
| 4716 |
1/2✓ Branch 0 taken 523 times.
✗ Branch 1 not taken.
|
523 | if (check_access(thd, UPDATE_ACL, "mysql", nullptr, nullptr, true, |
| 4717 |
4/4✓ Branch 0 taken 14 times.
✓ Branch 1 taken 509 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 520 times.
|
537 | true) && |
| 4718 |
3/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 11 times.
|
14 | check_global_access(thd, CREATE_USER_ACL)) |
| 4719 | 3 | break; | |
| 4720 | /* Conditionally writes to binlog */ | ||
| 4721 |
4/6✓ Branch 0 taken 514 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 412 times.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 412 times.
✗ Branch 5 not taken.
|
520 | if (!(res = mysql_rename_user(thd, lex->users_list))) my_ok(thd); |
| 4722 | 514 | break; | |
| 4723 | } | ||
| 4724 | 1698 | case SQLCOM_REVOKE_ALL: { | |
| 4725 |
1/2✓ Branch 0 taken 1698 times.
✗ Branch 1 not taken.
|
1698 | if (check_access(thd, UPDATE_ACL, "mysql", nullptr, nullptr, true, |
| 4726 |
4/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1691 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1696 times.
|
1705 | true) && |
| 4727 |
3/4✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
|
7 | check_global_access(thd, CREATE_USER_ACL)) |
| 4728 | 2 | break; | |
| 4729 | |||
| 4730 | /* Replicate current user as grantor */ | ||
| 4731 | 1696 | thd->binlog_invoker(); | |
| 4732 | |||
| 4733 | /* Conditionally writes to binlog */ | ||
| 4734 |
4/6✓ Branch 0 taken 1696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1663 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 1663 times.
✗ Branch 5 not taken.
|
1696 | if (!(res = mysql_revoke_all(thd, lex->users_list))) my_ok(thd); |
| 4735 | 1696 | break; | |
| 4736 | } | ||
| 4737 | 12918 | case SQLCOM_REVOKE: | |
| 4738 | case SQLCOM_GRANT: { | ||
| 4739 | /* GRANT ... AS preliminery checks */ | ||
| 4740 |
2/2✓ Branch 0 taken 446 times.
✓ Branch 1 taken 12472 times.
|
12918 | if (lex->grant_as.grant_as_used) { |
| 4741 |
4/4✓ Branch 0 taken 444 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 443 times.
|
446 | if ((first_table || query_block->db)) { |
| 4742 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | my_error(ER_UNSUPPORTED_USE_OF_GRANT_AS, MYF(0)); |
| 4743 | 3 | goto error; | |
| 4744 | } | ||
| 4745 | } | ||
| 4746 | /* | ||
| 4747 | Skip access check if we're granting a proxy | ||
| 4748 | */ | ||
| 4749 |
2/2✓ Branch 0 taken 12542 times.
✓ Branch 1 taken 373 times.
|
12915 | if (lex->type != TYPE_ENUM_PROXY) { |
| 4750 | /* | ||
| 4751 | If there are static grants in the GRANT statement or there are no | ||
| 4752 | dynamic privileges we perform check_access on GRANT_OPTION based on | ||
| 4753 | static global privilege level and set the DA accordingly. | ||
| 4754 | */ | ||
| 4755 |
4/4✓ Branch 0 taken 2623 times.
✓ Branch 1 taken 9919 times.
✓ Branch 2 taken 390 times.
✓ Branch 3 taken 2233 times.
|
12542 | if (lex->grant > 0 || lex->dynamic_privileges.elements == 0) { |
| 4756 | /* | ||
| 4757 | check_access sets DA error message based on GRANT arguments. | ||
| 4758 | */ | ||
| 4759 |
8/8✓ Branch 0 taken 2145 times.
✓ Branch 1 taken 8164 times.
✓ Branch 2 taken 2145 times.
✓ Branch 3 taken 8164 times.
✓ Branch 4 taken 2145 times.
✓ Branch 5 taken 8164 times.
✓ Branch 6 taken 88 times.
✓ Branch 7 taken 10221 times.
|
20618 | if (check_access( |
| 4760 |
1/2✓ Branch 0 taken 10309 times.
✗ Branch 1 not taken.
|
10309 | thd, lex->grant | lex->grant_tot_col | GRANT_ACL, |
| 4761 | first_table ? first_table->db : query_block->db, | ||
| 4762 | first_table ? &first_table->grant.privilege : nullptr, | ||
| 4763 | first_table ? &first_table->grant.m_internal : nullptr, | ||
| 4764 | first_table ? false : true, false)) { | ||
| 4765 | 88 | goto error; | |
| 4766 | } | ||
| 4767 | } | ||
| 4768 | /* | ||
| 4769 | ..else we still call check_access to load internal structures, but | ||
| 4770 | defer checking of global dynamic GRANT_OPTION to mysql_grant. We still | ||
| 4771 | ignore checks if this was a grant of a proxy. | ||
| 4772 | */ | ||
| 4773 | else { | ||
| 4774 | /* | ||
| 4775 | check_access will load grant.privilege and grant.m_internal with | ||
| 4776 | values which are used later during column privilege checking. The | ||
| 4777 | return value isn't interesting as we'll check for dynamic global | ||
| 4778 | privileges later. | ||
| 4779 | */ | ||
| 4780 |
7/8✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2231 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2231 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2231 times.
✓ Branch 6 taken 2233 times.
✗ Branch 7 not taken.
|
2233 | check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL, |
| 4781 | first_table ? first_table->db : query_block->db, | ||
| 4782 | first_table ? &first_table->grant.privilege : nullptr, | ||
| 4783 | first_table ? &first_table->grant.m_internal : nullptr, | ||
| 4784 | first_table ? false : true, true); | ||
| 4785 | } | ||
| 4786 | } | ||
| 4787 | |||
| 4788 | /* Replicate current user as grantor */ | ||
| 4789 | 12827 | thd->binlog_invoker(); | |
| 4790 | |||
| 4791 |
3/4✓ Branch 0 taken 12827 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11670 times.
✓ Branch 3 taken 1157 times.
|
12827 | if (thd->security_context()->user().str) // If not replication |
| 4792 | { | ||
| 4793 | LEX_USER *user, *tmp_user; | ||
| 4794 | 11670 | bool first_user = true; | |
| 4795 | |||
| 4796 |
1/2✓ Branch 0 taken 11670 times.
✗ Branch 1 not taken.
|
11670 | List_iterator<LEX_USER> user_list(lex->users_list); |
| 4797 |
2/2✓ Branch 0 taken 12444 times.
✓ Branch 1 taken 11662 times.
|
24106 | while ((tmp_user = user_list++)) { |
| 4798 |
3/4✓ Branch 0 taken 12444 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 12441 times.
|
12449 | if (!(user = get_current_user(thd, tmp_user))) goto error; |
| 4799 |
4/4✓ Branch 0 taken 123 times.
✓ Branch 1 taken 12318 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 12440 times.
|
12564 | if (specialflag & SPECIAL_NO_RESOLVE && |
| 4800 |
3/4✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 122 times.
|
123 | hostname_requires_resolving(user->host.str)) |
| 4801 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | push_warning(thd, Sql_condition::SL_WARNING, |
| 4802 | ER_WARN_HOSTNAME_WONT_WORK, | ||
| 4803 | ER_THD(thd, ER_WARN_HOSTNAME_WONT_WORK)); | ||
| 4804 | // Are we trying to change a password of another user | ||
| 4805 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12441 times.
|
12441 | assert(user->host.str != nullptr); |
| 4806 | |||
| 4807 | /* | ||
| 4808 | GRANT/REVOKE PROXY has the target user as a first entry in the list. | ||
| 4809 | */ | ||
| 4810 |
4/4✓ Branch 0 taken 744 times.
✓ Branch 1 taken 11697 times.
✓ Branch 2 taken 365 times.
✓ Branch 3 taken 379 times.
|
12441 | if (lex->type == TYPE_ENUM_PROXY && first_user) { |
| 4811 | 365 | first_user = false; | |
| 4812 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 360 times.
|
365 | if (acl_check_proxy_grant_access(thd, user->host.str, |
| 4813 | user->user.str, | ||
| 4814 |
1/2✓ Branch 0 taken 365 times.
✗ Branch 1 not taken.
|
365 | lex->grant & GRANT_ACL)) |
| 4815 | 5 | goto error; | |
| 4816 | } | ||
| 4817 | } | ||
| 4818 | } | ||
| 4819 |
2/2✓ Branch 0 taken 2123 times.
✓ Branch 1 taken 10696 times.
|
12819 | if (first_table) { |
| 4820 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2121 times.
|
2123 | if (lex->dynamic_privileges.elements > 0) { |
| 4821 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (thd->lex->grant_if_exists) { |
| 4822 | ✗ | push_warning_printf(thd, Sql_condition::SL_WARNING, | |
| 4823 | ER_ILLEGAL_PRIVILEGE_LEVEL, | ||
| 4824 | ER_THD(thd, ER_ILLEGAL_PRIVILEGE_LEVEL), | ||
| 4825 | all_tables->table_name); | ||
| 4826 | } else { | ||
| 4827 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | my_error(ER_ILLEGAL_PRIVILEGE_LEVEL, MYF(0), |
| 4828 | all_tables->table_name); | ||
| 4829 | 2 | goto error; | |
| 4830 | } | ||
| 4831 | } | ||
| 4832 |
2/2✓ Branch 0 taken 1923 times.
✓ Branch 1 taken 198 times.
|
2121 | if (lex->type == TYPE_ENUM_PROCEDURE || |
| 4833 |
2/2✓ Branch 0 taken 59 times.
✓ Branch 1 taken 1864 times.
|
1923 | lex->type == TYPE_ENUM_FUNCTION) { |
| 4834 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 252 times.
|
257 | uint grants = lex->all_privileges |
| 4835 | 5 | ? (PROC_OP_ACLS) | (lex->grant & GRANT_ACL) | |
| 4836 | : lex->grant; | ||
| 4837 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 254 times.
|
257 | if (check_grant_routine(thd, grants | GRANT_ACL, all_tables, |
| 4838 |
1/2✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
|
257 | lex->type == TYPE_ENUM_PROCEDURE, false)) |
| 4839 | 3 | goto error; | |
| 4840 | /* Conditionally writes to binlog */ | ||
| 4841 | 508 | res = mysql_routine_grant( | |
| 4842 | 254 | thd, all_tables, lex->type == TYPE_ENUM_PROCEDURE, | |
| 4843 |
1/2✓ Branch 0 taken 254 times.
✗ Branch 1 not taken.
|
254 | lex->users_list, grants, lex->sql_command == SQLCOM_REVOKE, true); |
| 4844 |
3/4✓ Branch 0 taken 221 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
|
254 | if (!res) my_ok(thd); |
| 4845 | 254 | } else { | |
| 4846 |
3/4✓ Branch 0 taken 1864 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 1850 times.
|
1864 | if (check_grant(thd, (lex->grant | lex->grant_tot_col | GRANT_ACL), |
| 4847 | all_tables, false, UINT_MAX, false)) | ||
| 4848 | 14 | goto error; | |
| 4849 | /* Conditionally writes to binlog */ | ||
| 4850 | res = | ||
| 4851 | 1850 | mysql_table_grant(thd, all_tables, lex->users_list, lex->columns, | |
| 4852 |
1/2✓ Branch 0 taken 1850 times.
✗ Branch 1 not taken.
|
1850 | lex->grant, lex->sql_command == SQLCOM_REVOKE); |
| 4853 | } | ||
| 4854 | } else { | ||
| 4855 |
1/2✓ Branch 0 taken 10696 times.
✗ Branch 1 not taken.
|
10696 | if (lex->columns.elements || |
| 4856 |
3/4✓ Branch 0 taken 368 times.
✓ Branch 1 taken 10328 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 368 times.
|
10696 | (lex->type && lex->type != TYPE_ENUM_PROXY)) { |
| 4857 | ✗ | my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); | |
| 4858 | ✗ | goto error; | |
| 4859 | } else { | ||
| 4860 | /* Dynamic privileges are allowed only for global grants */ | ||
| 4861 |
4/4✓ Branch 0 taken 2728 times.
✓ Branch 1 taken 7968 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 2720 times.
|
10696 | if (query_block->db && lex->dynamic_privileges.elements > 0) { |
| 4862 | 8 | String privs; | |
| 4863 | 8 | bool comma = false; | |
| 4864 |
5/8✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 8 times.
|
21 | for (const LEX_CSTRING &priv : lex->dynamic_privileges) { |
| 4865 |
3/4✓ Branch 0 taken 5 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
13 | if (comma) privs.append(","); |
| 4866 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | privs.append(priv.str, priv.length); |
| 4867 | 13 | comma = true; | |
| 4868 | } | ||
| 4869 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
|
8 | if (thd->lex->grant_if_exists) { |
| 4870 |
3/6✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
3 | push_warning_printf( |
| 4871 | thd, Sql_condition::SL_WARNING, ER_ILLEGAL_PRIVILEGE_LEVEL, | ||
| 4872 | ER_THD(thd, ER_ILLEGAL_PRIVILEGE_LEVEL), privs.c_ptr()); | ||
| 4873 | } else { | ||
| 4874 |
2/4✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
5 | my_error(ER_ILLEGAL_PRIVILEGE_LEVEL, MYF(0), privs.c_ptr()); |
| 4875 | 5 | goto error; | |
| 4876 | } | ||
| 4877 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
|
8 | } |
| 4878 | /* Conditionally writes to binlog */ | ||
| 4879 | 10679 | res = mysql_grant( | |
| 4880 | 10691 | thd, query_block->db, lex->users_list, lex->grant, | |
| 4881 | 10691 | lex->sql_command == SQLCOM_REVOKE, lex->type == TYPE_ENUM_PROXY, | |
| 4882 |
1/2✓ Branch 0 taken 10679 times.
✗ Branch 1 not taken.
|
10691 | lex->dynamic_privileges, lex->all_privileges, &lex->grant_as); |
| 4883 | } | ||
| 4884 | } | ||
| 4885 | 12783 | break; | |
| 4886 | } | ||
| 4887 | 26040 | case SQLCOM_RESET: | |
| 4888 | /* | ||
| 4889 | RESET commands are never written to the binary log, so we have to | ||
| 4890 | initialize this variable because RESET shares the same code as FLUSH | ||
| 4891 | */ | ||
| 4892 | 26040 | lex->no_write_to_binlog = true; | |
| 4893 |
3/4✓ Branch 0 taken 3851 times.
✓ Branch 1 taken 22189 times.
✓ Branch 2 taken 3851 times.
✗ Branch 3 not taken.
|
26040 | if ((lex->type & REFRESH_PERSIST) && (lex->option_type == OPT_PERSIST)) { |
| 4894 | Persisted_variables_cache *pv = | ||
| 4895 |
1/2✓ Branch 0 taken 3851 times.
✗ Branch 1 not taken.
|
3851 | Persisted_variables_cache::get_instance(); |
| 4896 |
1/2✓ Branch 0 taken 3851 times.
✗ Branch 1 not taken.
|
3851 | if (pv) |
| 4897 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 3824 times.
|
3851 | if (pv->reset_persisted_variables(thd, lex->name.str, |
| 4898 |
1/2✓ Branch 0 taken 3851 times.
✗ Branch 1 not taken.
|
3851 | lex->drop_if_exists)) |
| 4899 | 27 | goto error; | |
| 4900 |
1/2✓ Branch 0 taken 3824 times.
✗ Branch 1 not taken.
|
3824 | my_ok(thd); |
| 4901 | 3824 | break; | |
| 4902 | } | ||
| 4903 | [[fallthrough]]; | ||
| 4904 | case SQLCOM_FLUSH: { | ||
| 4905 | int write_to_binlog; | ||
| 4906 | |||
| 4907 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45345 times.
|
45345 | if (lex->type & DUMP_MEMORY_PROFILE) { |
| 4908 |
0/4✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
304 | if (check_global_access(thd, SUPER_ACL)) goto error; |
| 4909 |
3/4✓ Branch 0 taken 45345 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 283 times.
✓ Branch 3 taken 45062 times.
|
45345 | } else if (is_reload_request_denied(thd, lex->type)) |
| 4910 | 283 | goto error; | |
| 4911 | |||
| 4912 |
4/4✓ Branch 0 taken 711 times.
✓ Branch 1 taken 44351 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 634 times.
|
45062 | if (first_table && lex->type & REFRESH_READ_LOCK) { |
| 4913 | #ifdef WITH_WSREP | ||
| 4914 |
3/4✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 76 times.
|
84 | if (pxc_strict_mode_lock_check(thd)) goto error; |
| 4915 | 76 | bool already_paused = false; | |
| 4916 | #endif /* WITH_WSREP */ | ||
| 4917 | |||
| 4918 | /* | ||
| 4919 | Do not allow FLUSH TABLES <table_list> WITH READ LOCK under an active | ||
| 4920 | LOCK TABLES FOR BACKUP lock. | ||
| 4921 | */ | ||
| 4922 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
|
76 | if (thd->backup_tables_lock.abort_if_acquired()) goto error; |
| 4923 | |||
| 4924 | /* Check table-level privileges. */ | ||
| 4925 |
2/4✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76 times.
|
76 | if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, |
| 4926 | false, UINT_MAX, false)) | ||
| 4927 | ✗ | goto error; | |
| 4928 | |||
| 4929 | #ifdef WITH_WSREP | ||
| 4930 |
7/10✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 59 times.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 76 times.
|
92 | if (WSREP(thd) && |
| 4931 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
16 | !thd->global_read_lock.wsrep_pause_once(&already_paused)) |
| 4932 | ✗ | goto error; | |
| 4933 | |||
| 4934 |
3/4✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 69 times.
|
76 | if (flush_tables_with_read_lock(thd, all_tables)) { |
| 4935 |
6/10✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
|
7 | if (WSREP(thd) && !already_paused) |
| 4936 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | thd->global_read_lock.wsrep_resume_once(); |
| 4937 | 7 | goto error; | |
| 4938 | } | ||
| 4939 | #else | ||
| 4940 | if (flush_tables_with_read_lock(thd, all_tables)) goto error; | ||
| 4941 | #endif /* WITH_WSREP */ | ||
| 4942 | |||
| 4943 |
1/2✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
|
69 | my_ok(thd); |
| 4944 | 69 | break; | |
| 4945 |
4/4✓ Branch 0 taken 634 times.
✓ Branch 1 taken 44351 times.
✓ Branch 2 taken 337 times.
✓ Branch 3 taken 297 times.
|
44985 | } else if (first_table && lex->type & REFRESH_FOR_EXPORT) { |
| 4946 | #ifdef WITH_WSREP | ||
| 4947 |
3/4✓ Branch 0 taken 337 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 336 times.
|
349 | if (pxc_strict_mode_lock_check(thd)) goto error; |
| 4948 | 336 | bool already_paused = false; | |
| 4949 | #endif /* WITH_WSREP */ | ||
| 4950 | /* | ||
| 4951 | Do not allow FLUSH TABLES ... FOR EXPORT under an active LOCK TABLES | ||
| 4952 | FOR BACKUP lock. | ||
| 4953 | */ | ||
| 4954 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 336 times.
|
336 | if (thd->backup_tables_lock.abort_if_acquired()) goto error; |
| 4955 | |||
| 4956 | /* Check table-level privileges. */ | ||
| 4957 |
3/4✓ Branch 0 taken 336 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 334 times.
|
336 | if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, |
| 4958 | false, UINT_MAX, false)) | ||
| 4959 | 2 | goto error; | |
| 4960 | |||
| 4961 | #ifdef WITH_WSREP | ||
| 4962 |
7/10✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 315 times.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 334 times.
|
352 | if (WSREP(thd) && |
| 4963 |
2/4✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
|
18 | !thd->global_read_lock.wsrep_pause_once(&already_paused)) |
| 4964 | ✗ | goto error; | |
| 4965 | |||
| 4966 |
3/4✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 324 times.
|
334 | if (flush_tables_for_export(thd, all_tables)) { |
| 4967 |
7/10✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
|
10 | if (WSREP(thd) && !already_paused) |
| 4968 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | thd->global_read_lock.wsrep_resume_once(); |
| 4969 | 10 | goto error; | |
| 4970 | } | ||
| 4971 | #else | ||
| 4972 | if (flush_tables_for_export(thd, all_tables)) goto error; | ||
| 4973 | #endif /* WITH_WSREP */ | ||
| 4974 | |||
| 4975 |
1/2✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
|
324 | my_ok(thd); |
| 4976 | 324 | break; | |
| 4977 | } | ||
| 4978 | |||
| 4979 | #ifdef WITH_WSREP | ||
| 4980 | |||
| 4981 | /* FLUSH LOGS OR FLUSH BINARY LOGS are not replicated. | ||
| 4982 | Check git-hash#8aa97efd935a for more details. */ | ||
| 4983 | |||
| 4984 | /* REFRESH_TABLES is taken care inside handle_reload_request */ | ||
| 4985 |
2/2✓ Branch 0 taken 7482 times.
✓ Branch 1 taken 37166 times.
|
44648 | if (lex->type & |
| 4986 | (REFRESH_GRANT | REFRESH_HOSTS | REFRESH_STATUS | | ||
| 4987 | REFRESH_USER_RESOURCES | REFRESH_ERROR_LOG | REFRESH_SLOW_LOG | | ||
| 4988 | REFRESH_GENERAL_LOG | REFRESH_ENGINE_LOG | REFRESH_RELAY_LOG | | ||
| 4989 | /* Percona Server specific */ | ||
| 4990 | REFRESH_TABLE_STATS | | ||
| 4991 | REFRESH_INDEX_STATS | REFRESH_USER_STATS | REFRESH_CLIENT_STATS | | ||
| 4992 | REFRESH_THREAD_STATS)) { | ||
| 4993 |
12/18✓ Branch 0 taken 7482 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 490 times.
✓ Branch 3 taken 6992 times.
✓ Branch 4 taken 490 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 476 times.
✓ Branch 7 taken 14 times.
✓ Branch 8 taken 476 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 226 times.
✓ Branch 11 taken 250 times.
✓ Branch 12 taken 226 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 226 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 7482 times.
|
7482 | WSREP_TO_ISOLATION_BEGIN_WRTCHK(WSREP_MYSQL_DB, NULL, NULL) |
| 4994 | } | ||
| 4995 | #endif /* WITH_WSREP */ | ||
| 4996 | |||
| 4997 | /* | ||
| 4998 | handle_reload_request() will tell us if we are allowed to write to the | ||
| 4999 | binlog or not. | ||
| 5000 | */ | ||
| 5001 |
3/4✓ Branch 0 taken 44642 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41455 times.
✓ Branch 3 taken 3187 times.
|
44648 | if (!handle_reload_request(thd, lex->type, first_table, |
| 5002 | &write_to_binlog)) { | ||
| 5003 | #ifdef WITH_WSREP | ||
| 5004 |
2/2✓ Branch 0 taken 22208 times.
✓ Branch 1 taken 19247 times.
|
41455 | if ((lex->type & REFRESH_TABLES) && |
| 5005 |
2/2✓ Branch 0 taken 12337 times.
✓ Branch 1 taken 9871 times.
|
22208 | !(lex->type & (REFRESH_FOR_EXPORT | REFRESH_READ_LOCK))) { |
| 5006 | /* | ||
| 5007 | This is done after handle_reload_request is because | ||
| 5008 | LOCK TABLES is not replicated in galera, the upgrade of which | ||
| 5009 | is checked in handle_reload_request. | ||
| 5010 | Hence, done after/if we are able to upgrade locks. | ||
| 5011 | */ | ||
| 5012 |
2/2✓ Branch 0 taken 291 times.
✓ Branch 1 taken 12046 times.
|
12337 | if (first_table) { |
| 5013 |
12/18✓ Branch 0 taken 291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 273 times.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 15 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 12 times.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 12 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 12 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 291 times.
|
291 | WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table); |
| 5014 | } else { | ||
| 5015 |
13/18✓ Branch 0 taken 12046 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9498 times.
✓ Branch 3 taken 2548 times.
✓ Branch 4 taken 464 times.
✓ Branch 5 taken 9034 times.
✓ Branch 6 taken 11 times.
✓ Branch 7 taken 453 times.
✓ Branch 8 taken 11 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 10 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 10 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 12046 times.
|
12046 | WSREP_TO_ISOLATION_BEGIN_WRTCHK(WSREP_MYSQL_DB, NULL, NULL); |
| 5016 | } | ||
| 5017 | } | ||
| 5018 | #endif /* WITH_WSREP */ | ||
| 5019 | /* | ||
| 5020 | We WANT to write and we CAN write. | ||
| 5021 | ! we write after unlocking the table. | ||
| 5022 | */ | ||
| 5023 | /* | ||
| 5024 | Presumably, RESET and binlog writing doesn't require synchronization | ||
| 5025 | */ | ||
| 5026 | |||
| 5027 |
2/2✓ Branch 0 taken 19343 times.
✓ Branch 1 taken 22112 times.
|
41455 | if (write_to_binlog > 0) // we should write |
| 5028 | { | ||
| 5029 |
2/2✓ Branch 0 taken 19036 times.
✓ Branch 1 taken 307 times.
|
19343 | if (!lex->no_write_to_binlog) |
| 5030 |
1/2✓ Branch 0 taken 19035 times.
✗ Branch 1 not taken.
|
19036 | res = write_bin_log(thd, false, thd->query().str, |
| 5031 |
2/4✓ Branch 0 taken 19036 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19036 times.
✗ Branch 3 not taken.
|
19036 | thd->query().length); |
| 5032 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 22091 times.
|
22112 | } else if (write_to_binlog < 0) { |
| 5033 | /* | ||
| 5034 | We should not write, but rather report error because | ||
| 5035 | handle_reload_request binlog interactions failed | ||
| 5036 | */ | ||
| 5037 | 21 | res = 1; | |
| 5038 | } | ||
| 5039 | |||
| 5040 |
3/4✓ Branch 0 taken 41434 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 41435 times.
✗ Branch 3 not taken.
|
41454 | if (!res) my_ok(thd); |
| 5041 | } | ||
| 5042 | |||
| 5043 | 44642 | break; | |
| 5044 | } | ||
| 5045 | 2564 | case SQLCOM_KILL: { | |
| 5046 | 2564 | Item *it = lex->kill_value_list.head(); | |
| 5047 | |||
| 5048 |
3/4✓ Branch 0 taken 2564 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2563 times.
|
2564 | if (lex->table_or_sp_used()) { |
| 5049 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_NOT_SUPPORTED_YET, MYF(0), |
| 5050 | "Usage of subqueries or stored " | ||
| 5051 | "function calls as part of this statement"); | ||
| 5052 | 1 | goto error; | |
| 5053 | } | ||
| 5054 | |||
| 5055 |
7/12✓ Branch 0 taken 47 times.
✓ Branch 1 taken 2516 times.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2563 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2563 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2563 times.
|
2563 | if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1)) { |
| 5056 | ✗ | my_error(ER_SET_CONSTANTS_ONLY, MYF(0)); | |
| 5057 | ✗ | goto error; | |
| 5058 | } | ||
| 5059 | |||
| 5060 |
1/2✓ Branch 0 taken 2563 times.
✗ Branch 1 not taken.
|
2563 | my_thread_id thread_id = static_cast<my_thread_id>(it->val_int()); |
| 5061 |
2/4✓ Branch 0 taken 2563 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2563 times.
|
2563 | if (thd->is_error()) goto error; |
| 5062 | |||
| 5063 |
1/2✓ Branch 0 taken 2563 times.
✗ Branch 1 not taken.
|
2563 | sql_kill(thd, thread_id, lex->type & ONLY_KILL_QUERY); |
| 5064 | 2563 | break; | |
| 5065 | } | ||
| 5066 | 1141 | case SQLCOM_SHOW_CREATE_USER: { | |
| 5067 | #ifdef WITH_WSREP | ||
| 5068 |
10/16✓ Branch 0 taken 1141 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1140 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1140 times.
|
1141 | WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW); |
| 5069 | #endif /* WITH_WSREP */ | ||
| 5070 |
1/2✓ Branch 0 taken 1140 times.
✗ Branch 1 not taken.
|
1140 | LEX_USER *show_user = get_current_user(thd, lex->grant_user); |
| 5071 | 1140 | Security_context *sctx = thd->security_context(); | |
| 5072 | bool are_both_users_same = | ||
| 5073 |
3/4✓ Branch 0 taken 1140 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 155 times.
✓ Branch 3 taken 985 times.
|
1295 | !strcmp(sctx->priv_user().str, show_user->user.str) && |
| 5074 |
4/6✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 155 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 151 times.
✓ Branch 5 taken 4 times.
|
155 | !my_strcasecmp(system_charset_info, show_user->host.str, |
| 5075 | sctx->priv_host().str); | ||
| 5076 |
7/8✓ Branch 0 taken 989 times.
✓ Branch 1 taken 151 times.
✓ Branch 2 taken 989 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 981 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 1132 times.
✓ Branch 7 taken 8 times.
|
1140 | if (are_both_users_same || !check_access(thd, SELECT_ACL, "mysql", |
| 5077 | nullptr, nullptr, true, false)) | ||
| 5078 |
1/2✓ Branch 0 taken 1132 times.
✗ Branch 1 not taken.
|
1132 | res = mysql_show_create_user(thd, show_user, are_both_users_same); |
| 5079 | 1140 | break; | |
| 5080 | } | ||
| 5081 | 355100 | case SQLCOM_BEGIN: | |
| 5082 |
3/4✓ Branch 0 taken 355256 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 355247 times.
|
355100 | if (trans_begin(thd, lex->start_transaction_opt)) goto error; |
| 5083 |
1/2✓ Branch 0 taken 355422 times.
✗ Branch 1 not taken.
|
355247 | my_ok(thd); |
| 5084 | 355422 | break; | |
| 5085 | 273657 | case SQLCOM_COMMIT: { | |
| 5086 |
3/4✓ Branch 0 taken 10 times.
✓ Branch 1 taken 273647 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
|
273657 | assert(thd->lock == nullptr || |
| 5087 | thd->locked_tables_mode == LTM_LOCK_TABLES); | ||
| 5088 | 273657 | bool tx_chain = | |
| 5089 |
2/2✓ Branch 0 taken 273653 times.
✓ Branch 1 taken 4 times.
|
547310 | (lex->tx_chain == TVL_YES || |
| 5090 |
3/4✓ Branch 0 taken 9 times.
✓ Branch 1 taken 273644 times.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
|
273653 | (thd->variables.completion_type == 1 && lex->tx_chain != TVL_NO)); |
| 5091 | 273657 | bool tx_release = | |
| 5092 |
1/2✓ Branch 0 taken 273727 times.
✗ Branch 1 not taken.
|
547384 | (lex->tx_release == TVL_YES || |
| 5093 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 273726 times.
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
|
273727 | (thd->variables.completion_type == 2 && lex->tx_release != TVL_NO)); |
| 5094 |
3/4✓ Branch 0 taken 273783 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 104 times.
✓ Branch 3 taken 273679 times.
|
273657 | if (trans_commit(thd)) goto error; |
| 5095 |
1/2✓ Branch 0 taken 273920 times.
✗ Branch 1 not taken.
|
273679 | thd->mdl_context.release_transactional_locks(); |
| 5096 | /* Begin transaction with the same isolation level. */ | ||
| 5097 |
2/2✓ Branch 0 taken 19 times.
✓ Branch 1 taken 273901 times.
|
273920 | if (tx_chain) { |
| 5098 | #ifdef WITH_WSREP | ||
| 5099 | /* We need to cleanup wsrep state before starting | ||
| 5100 | new transaction. If 'regular' commit was issued, | ||
| 5101 | it would be done in caller function wsrep_dispatch_sql_command() | ||
| 5102 | after returning from here. | ||
| 5103 | But now we need to do it in between. | ||
| 5104 | */ | ||
| 5105 |
1/2✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
|
19 | wsrep_after_statement(thd); |
| 5106 | #endif /* WITH_WSREP */ | ||
| 5107 |
2/4✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
|
19 | if (trans_begin(thd)) goto error; |
| 5108 | } else { | ||
| 5109 | /* Reset the isolation level and access mode if no chaining | ||
| 5110 | * transaction.*/ | ||
| 5111 |
1/2✓ Branch 0 taken 273729 times.
✗ Branch 1 not taken.
|
273901 | trans_reset_one_shot_chistics(thd); |
| 5112 | } | ||
| 5113 | /* Disconnect the current client connection. */ | ||
| 5114 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 273744 times.
|
273748 | if (tx_release) thd->killed = THD::KILL_CONNECTION; |
| 5115 |
1/2✓ Branch 0 taken 273878 times.
✗ Branch 1 not taken.
|
273748 | my_ok(thd); |
| 5116 | 273878 | break; | |
| 5117 | } | ||
| 5118 | 10716 | case SQLCOM_ROLLBACK: { | |
| 5119 |
3/4✓ Branch 0 taken 43 times.
✓ Branch 1 taken 10673 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 43 times.
|
10716 | assert(thd->lock == nullptr || |
| 5120 | thd->locked_tables_mode == LTM_LOCK_TABLES); | ||
| 5121 | 10716 | bool tx_chain = | |
| 5122 |
2/2✓ Branch 0 taken 10712 times.
✓ Branch 1 taken 4 times.
|
21428 | (lex->tx_chain == TVL_YES || |
| 5123 |
4/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10709 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
|
10712 | (thd->variables.completion_type == 1 && lex->tx_chain != TVL_NO)); |
| 5124 | 10716 | bool tx_release = | |
| 5125 |
2/2✓ Branch 0 taken 10714 times.
✓ Branch 1 taken 2 times.
|
21430 | (lex->tx_release == TVL_YES || |
| 5126 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10713 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
10714 | (thd->variables.completion_type == 2 && lex->tx_release != TVL_NO)); |
| 5127 |
2/4✓ Branch 0 taken 10704 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10704 times.
|
10716 | if (trans_rollback(thd)) goto error; |
| 5128 |
1/2✓ Branch 0 taken 10704 times.
✗ Branch 1 not taken.
|
10704 | thd->mdl_context.release_transactional_locks(); |
| 5129 | /* Begin transaction with the same isolation level. */ | ||
| 5130 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10698 times.
|
10704 | if (tx_chain) { |
| 5131 | #ifdef WITH_WSREP | ||
| 5132 | /* We need to cleanup wsrep state before starting | ||
| 5133 | new transaction. If 'regular' rollback was issued, | ||
| 5134 | it would be done in caller function wsrep_dispatch_sql_command() | ||
| 5135 | after returning from here. | ||
| 5136 | But now we need to do it in between. | ||
| 5137 | */ | ||
| 5138 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | wsrep_after_statement(thd); |
| 5139 | #endif /* WITH_WSREP */ | ||
| 5140 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
6 | if (trans_begin(thd)) goto error; |
| 5141 | } else { | ||
| 5142 | /* Reset the isolation level and access mode if no chaining | ||
| 5143 | * transaction.*/ | ||
| 5144 |
1/2✓ Branch 0 taken 10698 times.
✗ Branch 1 not taken.
|
10698 | trans_reset_one_shot_chistics(thd); |
| 5145 | } | ||
| 5146 | /* Disconnect the current client connection. */ | ||
| 5147 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10701 times.
|
10704 | if (tx_release) thd->killed = THD::KILL_CONNECTION; |
| 5148 |
1/2✓ Branch 0 taken 10704 times.
✗ Branch 1 not taken.
|
10704 | my_ok(thd); |
| 5149 | 10704 | break; | |
| 5150 | } | ||
| 5151 | 38 | case SQLCOM_RELEASE_SAVEPOINT: | |
| 5152 |
3/4✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 34 times.
|
38 | if (trans_release_savepoint(thd, lex->ident)) goto error; |
| 5153 |
1/2✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
|
34 | my_ok(thd); |
| 5154 | 34 | break; | |
| 5155 | 4286 | case SQLCOM_ROLLBACK_TO_SAVEPOINT: | |
| 5156 |
3/4✓ Branch 0 taken 4286 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 4265 times.
|
4286 | if (trans_rollback_to_savepoint(thd, lex->ident)) goto error; |
| 5157 |
1/2✓ Branch 0 taken 4265 times.
✗ Branch 1 not taken.
|
4265 | my_ok(thd); |
| 5158 | 4265 | break; | |
| 5159 | 8288 | case SQLCOM_SAVEPOINT: | |
| 5160 |
3/4✓ Branch 0 taken 8287 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 8283 times.
|
8288 | if (trans_savepoint(thd, lex->ident)) goto error; |
| 5161 |
1/2✓ Branch 0 taken 8285 times.
✗ Branch 1 not taken.
|
8283 | my_ok(thd); |
| 5162 | 8285 | break; | |
| 5163 | 36017 | case SQLCOM_CREATE_PROCEDURE: | |
| 5164 | case SQLCOM_CREATE_SPFUNCTION: { | ||
| 5165 | uint namelen; | ||
| 5166 | char *name; | ||
| 5167 | |||
| 5168 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36017 times.
|
36017 | assert(lex->sphead != nullptr); |
| 5169 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36017 times.
|
36017 | assert(lex->sphead->m_db.str); /* Must be initialized in the parser */ |
| 5170 | /* | ||
| 5171 | Verify that the database name is allowed, optionally | ||
| 5172 | lowercase it. | ||
| 5173 | */ | ||
| 5174 |
2/4✓ Branch 0 taken 36017 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36017 times.
|
36017 | if (check_and_convert_db_name(&lex->sphead->m_db, false) != |
| 5175 | Ident_name_check::OK) | ||
| 5176 | 26 | goto error; | |
| 5177 | |||
| 5178 |
3/4✓ Branch 0 taken 36017 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 35996 times.
|
36017 | if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, nullptr, |
| 5179 | nullptr, false, false)) | ||
| 5180 | 21 | goto error; | |
| 5181 | |||
| 5182 | 35996 | name = lex->sphead->name(&namelen); | |
| 5183 |
2/2✓ Branch 0 taken 18665 times.
✓ Branch 1 taken 17331 times.
|
35996 | if (lex->sphead->m_type == enum_sp_type::FUNCTION) { |
| 5184 |
1/2✓ Branch 0 taken 18665 times.
✗ Branch 1 not taken.
|
18665 | udf_func *udf = find_udf(name, namelen); |
| 5185 | /* | ||
| 5186 | Issue a warning if there is an existing loadable function with the | ||
| 5187 | same name. | ||
| 5188 | */ | ||
| 5189 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18663 times.
|
18665 | if (udf) { |
| 5190 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | push_warning_printf(thd, Sql_condition::SL_NOTE, |
| 5191 | ER_WARN_SF_UDF_NAME_COLLISION, | ||
| 5192 | ER_THD(thd, ER_WARN_SF_UDF_NAME_COLLISION), name); | ||
| 5193 | } | ||
| 5194 | } | ||
| 5195 | |||
| 5196 |
3/4✓ Branch 0 taken 35996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 35991 times.
|
35996 | if (sp_process_definer(thd)) goto error; |
| 5197 | |||
| 5198 | /* | ||
| 5199 | Record the CURRENT_USER in binlog. The CURRENT_USER is used on slave to | ||
| 5200 | grant default privileges when sp_automatic_privileges variable is set. | ||
| 5201 | */ | ||
| 5202 | 35991 | thd->binlog_invoker(); | |
| 5203 | |||
| 5204 | #ifdef WITH_WSREP | ||
| 5205 |
9/14✓ Branch 0 taken 35991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9563 times.
✓ Branch 3 taken 26428 times.
✓ Branch 4 taken 99 times.
✓ Branch 5 taken 9464 times.
✓ Branch 6 taken 99 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 99 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 99 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 35991 times.
|
35991 | WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) |
| 5206 | #endif /* WITH_WSREP */ | ||
| 5207 | |||
| 5208 | 35991 | bool sp_already_exists = false; | |
| 5209 |
2/2✓ Branch 0 taken 35910 times.
✓ Branch 1 taken 69 times.
|
35979 | if (!(res = sp_create_routine( |
| 5210 | 35991 | thd, lex->sphead, thd->lex->definer, | |
| 5211 |
1/2✓ Branch 0 taken 35979 times.
✗ Branch 1 not taken.
|
35991 | thd->lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS, |
| 5212 | sp_already_exists))) { | ||
| 5213 |
2/2✓ Branch 0 taken 35902 times.
✓ Branch 1 taken 8 times.
|
35910 | if (!sp_already_exists) { |
| 5214 | /* only add privileges if really necessary */ | ||
| 5215 | |||
| 5216 |
1/2✓ Branch 0 taken 35902 times.
✗ Branch 1 not taken.
|
35902 | Security_context security_context; |
| 5217 | 35902 | bool restore_backup_context = false; | |
| 5218 | 35902 | Security_context *backup = nullptr; | |
| 5219 | /* | ||
| 5220 | We're going to issue an implicit GRANT statement so we close all | ||
| 5221 | open tables. We have to keep metadata locks as this ensures that | ||
| 5222 | this statement is atomic against concurrent FLUSH TABLES WITH READ | ||
| 5223 | LOCK. Deadlocks which can arise due to fact that this implicit | ||
| 5224 | statement takes metadata locks should be detected by a deadlock | ||
| 5225 | detector in MDL subsystem and reported as errors. | ||
| 5226 | |||
| 5227 | No need to commit/rollback statement transaction, it's not started. | ||
| 5228 | |||
| 5229 | TODO: Long-term we should either ensure that implicit GRANT | ||
| 5230 | statement is written into binary log as a separate statement or make | ||
| 5231 | both creation of routine and implicit GRANT parts of one fully | ||
| 5232 | atomic statement. | ||
| 5233 | */ | ||
| 5234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35902 times.
|
35902 | assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT)); |
| 5235 |
1/2✓ Branch 0 taken 35902 times.
✗ Branch 1 not taken.
|
35902 | close_thread_tables(thd); |
| 5236 | /* | ||
| 5237 | Check if invoker exists on slave, then use invoker privilege to | ||
| 5238 | insert routine privileges to mysql.procs_priv. If invoker is not | ||
| 5239 | available then consider using definer. | ||
| 5240 | |||
| 5241 | Check if the definer exists on slave, | ||
| 5242 | then use definer privilege to insert routine privileges to | ||
| 5243 | mysql.procs_priv. | ||
| 5244 | |||
| 5245 | For current user of SQL thread has GLOBAL_ACL privilege, | ||
| 5246 | which doesn't any check routine privileges, | ||
| 5247 | so no routine privilege record will insert into mysql.procs_priv. | ||
| 5248 | */ | ||
| 5249 | |||
| 5250 |
2/2✓ Branch 0 taken 1780 times.
✓ Branch 1 taken 34122 times.
|
35902 | if (thd->slave_thread) { |
| 5251 | LEX_CSTRING current_user; | ||
| 5252 | LEX_CSTRING current_host; | ||
| 5253 |
2/2✓ Branch 0 taken 1771 times.
✓ Branch 1 taken 9 times.
|
1780 | if (thd->has_invoker()) { |
| 5254 | 1771 | current_host = thd->get_invoker_host(); | |
| 5255 | 1771 | current_user = thd->get_invoker_user(); | |
| 5256 | } else { | ||
| 5257 | 9 | current_host = lex->definer->host; | |
| 5258 | 9 | current_user = lex->definer->user; | |
| 5259 | } | ||
| 5260 |
3/4✓ Branch 0 taken 1780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1777 times.
✓ Branch 3 taken 3 times.
|
1780 | if (is_acl_user(thd, current_host.str, current_user.str)) { |
| 5261 | 1777 | security_context.change_security_context( | |
| 5262 |
1/2✓ Branch 0 taken 1777 times.
✗ Branch 1 not taken.
|
1777 | thd, current_user, current_host, thd->lex->sphead->m_db.str, |
| 5263 | &backup); | ||
| 5264 | 1777 | restore_backup_context = true; | |
| 5265 | } | ||
| 5266 | } | ||
| 5267 | |||
| 5268 |
6/6✓ Branch 0 taken 35169 times.
✓ Branch 1 taken 733 times.
✓ Branch 2 taken 16320 times.
✓ Branch 3 taken 18849 times.
✓ Branch 4 taken 103 times.
✓ Branch 5 taken 35799 times.
|
52222 | if (sp_automatic_privileges && !opt_noacl && |
| 5269 |
2/2✓ Branch 0 taken 103 times.
✓ Branch 1 taken 16217 times.
|
16320 | check_routine_access( |
| 5270 | 16320 | thd, DEFAULT_CREATE_PROC_ACLS, lex->sphead->m_db.str, name, | |
| 5271 |
1/2✓ Branch 0 taken 16320 times.
✗ Branch 1 not taken.
|
16320 | lex->sql_command == SQLCOM_CREATE_PROCEDURE, true)) { |
| 5272 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
|
103 | if (sp_grant_privileges( |
| 5273 | 103 | thd, lex->sphead->m_db.str, name, | |
| 5274 |
1/2✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
|
103 | lex->sql_command == SQLCOM_CREATE_PROCEDURE)) |
| 5275 | ✗ | push_warning(thd, Sql_condition::SL_WARNING, | |
| 5276 | ER_PROC_AUTO_GRANT_FAIL, | ||
| 5277 | ER_THD(thd, ER_PROC_AUTO_GRANT_FAIL)); | ||
| 5278 |
1/2✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
|
103 | thd->clear_error(); |
| 5279 | } | ||
| 5280 | |||
| 5281 | /* | ||
| 5282 | Restore current user with GLOBAL_ACL privilege of SQL thread | ||
| 5283 | */ | ||
| 5284 |
2/2✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 34125 times.
|
35902 | if (restore_backup_context) { |
| 5285 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1777 times.
|
1777 | assert(thd->slave_thread == 1); |
| 5286 |
1/2✓ Branch 0 taken 1777 times.
✗ Branch 1 not taken.
|
1777 | thd->security_context()->restore_security_context(thd, backup); |
| 5287 | } | ||
| 5288 | 35902 | } | |
| 5289 |
1/2✓ Branch 0 taken 35910 times.
✗ Branch 1 not taken.
|
35910 | my_ok(thd); |
| 5290 | } | ||
| 5291 | 35979 | break; /* break super switch */ | |
| 5292 | } /* end case group bracket */ | ||
| 5293 | |||
| 5294 | 388 | case SQLCOM_ALTER_PROCEDURE: | |
| 5295 | case SQLCOM_ALTER_FUNCTION: { | ||
| 5296 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 382 times.
|
388 | if (check_routine_access(thd, ALTER_PROC_ACL, lex->spname->m_db.str, |
| 5297 | 388 | lex->spname->m_name.str, | |
| 5298 |
1/2✓ Branch 0 taken 388 times.
✗ Branch 1 not taken.
|
388 | lex->sql_command == SQLCOM_ALTER_PROCEDURE, |
| 5299 | false)) | ||
| 5300 | 6 | goto error; | |
| 5301 | |||
| 5302 | 764 | enum_sp_type sp_type = (lex->sql_command == SQLCOM_ALTER_PROCEDURE) | |
| 5303 |
2/2✓ Branch 0 taken 208 times.
✓ Branch 1 taken 174 times.
|
382 | ? enum_sp_type::PROCEDURE |
| 5304 | : enum_sp_type::FUNCTION; | ||
| 5305 | /* | ||
| 5306 | Note that if you implement the capability of ALTER FUNCTION to | ||
| 5307 | alter the body of the function, this command should be made to | ||
| 5308 | follow the restrictions that log-bin-trust-function-creators=0 | ||
| 5309 | already puts on CREATE FUNCTION. | ||
| 5310 | */ | ||
| 5311 | |||
| 5312 | #ifdef WITH_WSREP | ||
| 5313 | // to isolation is now done as part of sp_update_routine as it does | ||
| 5314 | // additional ACL based check that ensures the fact that if the | ||
| 5315 | // definer has SUPER PRIVILIGES then DROP/ALTER should have same too. | ||
| 5316 | // WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) | ||
| 5317 | // WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) | ||
| 5318 | #endif /* WITH_WSREP */ | ||
| 5319 | |||
| 5320 | /* Conditionally writes to binlog */ | ||
| 5321 |
1/2✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
|
382 | res = sp_update_routine(thd, sp_type, lex->spname, &lex->sp_chistics); |
| 5322 |
6/6✓ Branch 0 taken 330 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 324 times.
✓ Branch 4 taken 46 times.
✓ Branch 5 taken 324 times.
|
370 | if (res || thd->killed) goto error; |
| 5323 | |||
| 5324 |
1/2✓ Branch 0 taken 324 times.
✗ Branch 1 not taken.
|
324 | my_ok(thd); |
| 5325 | 324 | break; | |
| 5326 | } | ||
| 5327 | 37874 | case SQLCOM_DROP_PROCEDURE: | |
| 5328 | case SQLCOM_DROP_FUNCTION: { | ||
| 5329 |
2/2✓ Branch 0 taken 18374 times.
✓ Branch 1 taken 19500 times.
|
37874 | if (lex->sql_command == SQLCOM_DROP_FUNCTION && |
| 5330 |
2/2✓ Branch 0 taken 16913 times.
✓ Branch 1 taken 1461 times.
|
18374 | !lex->spname->m_explicit_name) { |
| 5331 | /* DROP FUNCTION <non qualified name> */ | ||
| 5332 | udf_func *udf = | ||
| 5333 |
1/2✓ Branch 0 taken 16913 times.
✗ Branch 1 not taken.
|
16913 | find_udf(lex->spname->m_name.str, lex->spname->m_name.length); |
| 5334 |
2/2✓ Branch 0 taken 196 times.
✓ Branch 1 taken 16717 times.
|
16913 | if (udf) { |
| 5335 |
2/4✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 196 times.
|
196 | if (check_access(thd, DELETE_ACL, "mysql", nullptr, nullptr, true, |
| 5336 | false)) | ||
| 5337 | ✗ | goto error; | |
| 5338 | |||
| 5339 | #ifdef WITH_WSREP | ||
| 5340 |
8/14✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 194 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 196 times.
|
196 | WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) |
| 5341 | #endif /* WITH_WSREP */ | ||
| 5342 | |||
| 5343 |
3/4✓ Branch 0 taken 190 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 184 times.
✓ Branch 3 taken 6 times.
|
196 | if (!(res = mysql_drop_function(thd, &lex->spname->m_name))) { |
| 5344 |
1/2✓ Branch 0 taken 184 times.
✗ Branch 1 not taken.
|
184 | my_ok(thd); |
| 5345 | 184 | break; | |
| 5346 | } | ||
| 5347 | 6 | my_error(ER_SP_DROP_FAILED, MYF(0), "FUNCTION (UDF)", | |
| 5348 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | lex->spname->m_name.str); |
| 5349 | 6 | goto error; | |
| 5350 | } | ||
| 5351 | |||
| 5352 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16715 times.
|
16717 | if (lex->spname->m_db.str == nullptr) { |
| 5353 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (lex->drop_if_exists) { |
| 5354 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | push_warning_printf(thd, Sql_condition::SL_NOTE, |
| 5355 | ER_SP_DOES_NOT_EXIST, | ||
| 5356 | ER_THD(thd, ER_SP_DOES_NOT_EXIST), | ||
| 5357 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | "FUNCTION (UDF)", lex->spname->m_name.str); |
| 5358 | 1 | res = false; | |
| 5359 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_ok(thd); |
| 5360 | 1 | break; | |
| 5361 | } | ||
| 5362 | 1 | my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION (UDF)", | |
| 5363 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | lex->spname->m_name.str); |
| 5364 | 1 | goto error; | |
| 5365 | } | ||
| 5366 | /* Fall thought to test for a stored function */ | ||
| 5367 | } | ||
| 5368 | |||
| 5369 | 37676 | const char *db = lex->spname->m_db.str; | |
| 5370 | 37676 | char *name = lex->spname->m_name.str; | |
| 5371 | |||
| 5372 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 37656 times.
|
37676 | if (check_routine_access(thd, ALTER_PROC_ACL, db, name, |
| 5373 |
1/2✓ Branch 0 taken 37676 times.
✗ Branch 1 not taken.
|
37676 | lex->sql_command == SQLCOM_DROP_PROCEDURE, |
| 5374 | false)) | ||
| 5375 | 20 | goto error; | |
| 5376 | |||
| 5377 | #ifdef WITH_WSREP | ||
| 5378 | // to isolation is now done as part of sp_drop_routine as it does | ||
| 5379 | // additional ACL based check that ensures the fact that if the | ||
| 5380 | // definer has SUPER PRIVILIGES then DROP/ATLER should have same too. | ||
| 5381 | // WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) | ||
| 5382 | #endif /* WITH_WSREP */ | ||
| 5383 | |||
| 5384 | 75312 | enum_sp_type sp_type = (lex->sql_command == SQLCOM_DROP_PROCEDURE) | |
| 5385 |
2/2✓ Branch 0 taken 19486 times.
✓ Branch 1 taken 18170 times.
|
37656 | ? enum_sp_type::PROCEDURE |
| 5386 | : enum_sp_type::FUNCTION; | ||
| 5387 | |||
| 5388 | /* Conditionally writes to binlog */ | ||
| 5389 | enum_sp_return_code sp_result = | ||
| 5390 |
1/2✓ Branch 0 taken 37644 times.
✗ Branch 1 not taken.
|
37656 | sp_drop_routine(thd, sp_type, lex->spname); |
| 5391 | |||
| 5392 | /* | ||
| 5393 | We're going to issue an implicit REVOKE statement so we close all | ||
| 5394 | open tables. We have to keep metadata locks as this ensures that | ||
| 5395 | this statement is atomic against concurrent FLUSH TABLES WITH READ | ||
| 5396 | LOCK. Deadlocks which can arise due to fact that this implicit | ||
| 5397 | statement takes metadata locks should be detected by a deadlock | ||
| 5398 | detector in MDL subsystem and reported as errors. | ||
| 5399 | |||
| 5400 | No need to commit/rollback statement transaction, it's not started. | ||
| 5401 | |||
| 5402 | TODO: Long-term we should either ensure that implicit REVOKE statement | ||
| 5403 | is written into binary log as a separate statement or make both | ||
| 5404 | dropping of routine and implicit REVOKE parts of one fully atomic | ||
| 5405 | statement. | ||
| 5406 | */ | ||
| 5407 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 37644 times.
|
37644 | assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT)); |
| 5408 |
1/2✓ Branch 0 taken 37644 times.
✗ Branch 1 not taken.
|
37644 | close_thread_tables(thd); |
| 5409 | |||
| 5410 | #ifdef WITH_WSREP | ||
| 5411 | // sp_drop_routine() returns SP_INTERNAL_ERROR in case of system user | ||
| 5412 | // privileges check failure. In such a case we don't want to proceed with | ||
| 5413 | // sp_revoke_privileges which will fail anyway. | ||
| 5414 |
2/2✓ Branch 0 taken 37637 times.
✓ Branch 1 taken 7 times.
|
37644 | if (sp_result != SP_INTERNAL_ERROR) { |
| 5415 | #endif | ||
| 5416 |
2/2✓ Branch 0 taken 21800 times.
✓ Branch 1 taken 732 times.
|
22532 | if (sp_result != SP_DOES_NOT_EXISTS && sp_automatic_privileges && |
| 5417 |
6/6✓ Branch 0 taken 22532 times.
✓ Branch 1 taken 15105 times.
✓ Branch 2 taken 13165 times.
✓ Branch 3 taken 8635 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 37601 times.
|
73334 | !opt_noacl && |
| 5418 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 13129 times.
|
13165 | sp_revoke_privileges(thd, db, name, |
| 5419 |
1/2✓ Branch 0 taken 13165 times.
✗ Branch 1 not taken.
|
13165 | lex->sql_command == SQLCOM_DROP_PROCEDURE)) { |
| 5420 |
2/4✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
36 | push_warning(thd, Sql_condition::SL_WARNING, ER_PROC_AUTO_REVOKE_FAIL, |
| 5421 | ER_THD(thd, ER_PROC_AUTO_REVOKE_FAIL)); | ||
| 5422 | /* If this happens, an error should have been reported. */ | ||
| 5423 | 36 | goto error; | |
| 5424 | } | ||
| 5425 | #ifdef WITH_WSREP | ||
| 5426 | } | ||
| 5427 | #endif | ||
| 5428 | |||
| 5429 | 37608 | res = sp_result; | |
| 5430 |
3/3✓ Branch 0 taken 22494 times.
✓ Branch 1 taken 15105 times.
✓ Branch 2 taken 9 times.
|
37608 | switch (sp_result) { |
| 5431 | 22494 | case SP_OK: | |
| 5432 |
1/2✓ Branch 0 taken 22494 times.
✗ Branch 1 not taken.
|
22494 | my_ok(thd); |
| 5433 | 22494 | break; | |
| 5434 | 15105 | case SP_DOES_NOT_EXISTS: | |
| 5435 |
2/2✓ Branch 0 taken 15072 times.
✓ Branch 1 taken 33 times.
|
15105 | if (lex->drop_if_exists) { |
| 5436 | res = | ||
| 5437 |
3/6✓ Branch 0 taken 15072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15072 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15072 times.
✗ Branch 5 not taken.
|
15072 | write_bin_log(thd, true, thd->query().str, thd->query().length); |
| 5438 |
2/4✓ Branch 0 taken 15072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15072 times.
✗ Branch 3 not taken.
|
15072 | push_warning_printf(thd, Sql_condition::SL_NOTE, |
| 5439 | ER_SP_DOES_NOT_EXIST, | ||
| 5440 | ER_THD(thd, ER_SP_DOES_NOT_EXIST), | ||
| 5441 |
5/8✓ Branch 0 taken 15072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15072 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15072 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5286 times.
✓ Branch 7 taken 9786 times.
|
15072 | SP_COM_STRING(lex), lex->spname->m_qname.str); |
| 5442 |
2/4✓ Branch 0 taken 15072 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15072 times.
✗ Branch 3 not taken.
|
15072 | if (!res) my_ok(thd); |
| 5443 | 15072 | break; | |
| 5444 | } | ||
| 5445 |
5/8✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
|
33 | my_error(ER_SP_DOES_NOT_EXIST, MYF(0), SP_COM_STRING(lex), |
| 5446 |
1/2✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
|
33 | lex->spname->m_qname.str); |
| 5447 | 33 | goto error; | |
| 5448 | 9 | default: | |
| 5449 |
5/8✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 9 times.
✗ Branch 7 not taken.
|
9 | my_error(ER_SP_DROP_FAILED, MYF(0), SP_COM_STRING(lex), |
| 5450 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | lex->spname->m_qname.str); |
| 5451 | 9 | goto error; | |
| 5452 | } | ||
| 5453 | 37566 | break; | |
| 5454 | } | ||
| 5455 | 67480 | case SQLCOM_CREATE_VIEW: { | |
| 5456 | /* | ||
| 5457 | Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands | ||
| 5458 | as specified through the thd->lex->create_view_mode flag. | ||
| 5459 | */ | ||
| 5460 |
1/2✓ Branch 0 taken 67468 times.
✗ Branch 1 not taken.
|
67480 | res = mysql_create_view(thd, first_table, thd->lex->create_view_mode); |
| 5461 | 67468 | break; | |
| 5462 | } | ||
| 5463 | 4822 | case SQLCOM_DROP_VIEW: { | |
| 5464 |
3/4✓ Branch 0 taken 4822 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4820 times.
|
4822 | if (check_table_access(thd, DROP_ACL, all_tables, false, UINT_MAX, false)) |
| 5465 | 2 | goto error; | |
| 5466 | |||
| 5467 | #ifdef WITH_WSREP | ||
| 5468 | // check is now done as part od drop view post definer SUPER PRIVILIGES | ||
| 5469 | // check. WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) | ||
| 5470 | #endif /* WITH_WSREP */ | ||
| 5471 | |||
| 5472 | /* Conditionally writes to binlog. */ | ||
| 5473 |
1/2✓ Branch 0 taken 4814 times.
✗ Branch 1 not taken.
|
4820 | res = mysql_drop_view(thd, first_table); |
| 5474 | 4814 | break; | |
| 5475 | } | ||
| 5476 | 23839 | case SQLCOM_CREATE_TRIGGER: | |
| 5477 | case SQLCOM_DROP_TRIGGER: { | ||
| 5478 | /* Conditionally writes to binlog. */ | ||
| 5479 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 23839 times.
|
23839 | assert(lex->m_sql_cmd != nullptr); |
| 5480 | 23839 | static_cast<Sql_cmd_ddl_trigger_common *>(lex->m_sql_cmd) | |
| 5481 | 23839 | ->set_table(all_tables); | |
| 5482 | |||
| 5483 |
1/2✓ Branch 0 taken 23827 times.
✗ Branch 1 not taken.
|
23839 | res = lex->m_sql_cmd->execute(thd); |
| 5484 | 23827 | break; | |
| 5485 | } | ||
| 5486 | 3702 | case SQLCOM_BINLOG_BASE64_EVENT: { | |
| 5487 |
1/2✓ Branch 0 taken 3702 times.
✗ Branch 1 not taken.
|
3702 | mysql_client_binlog_statement(thd); |
| 5488 | 3702 | break; | |
| 5489 | } | ||
| 5490 | 158956 | case SQLCOM_ANALYZE: | |
| 5491 | case SQLCOM_CHECK: | ||
| 5492 | case SQLCOM_OPTIMIZE: | ||
| 5493 | case SQLCOM_REPAIR: | ||
| 5494 | case SQLCOM_TRUNCATE: | ||
| 5495 | case SQLCOM_ALTER_TABLE: | ||
| 5496 | case SQLCOM_HA_OPEN: | ||
| 5497 | case SQLCOM_HA_READ: | ||
| 5498 | case SQLCOM_HA_CLOSE: | ||
| 5499 |
2/4✓ Branch 0 taken 158956 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 158956 times.
✗ Branch 3 not taken.
|
158956 | assert(first_table == all_tables && first_table != nullptr); |
| 5500 | [[fallthrough]]; | ||
| 5501 | case SQLCOM_CREATE_SERVER: | ||
| 5502 | case SQLCOM_CREATE_RESOURCE_GROUP: | ||
| 5503 | case SQLCOM_ALTER_SERVER: | ||
| 5504 | case SQLCOM_ALTER_RESOURCE_GROUP: | ||
| 5505 | case SQLCOM_DROP_RESOURCE_GROUP: | ||
| 5506 | case SQLCOM_DROP_SERVER: | ||
| 5507 | case SQLCOM_SET_RESOURCE_GROUP: | ||
| 5508 | case SQLCOM_SIGNAL: | ||
| 5509 | case SQLCOM_RESIGNAL: | ||
| 5510 | case SQLCOM_GET_DIAGNOSTICS: | ||
| 5511 | case SQLCOM_CHANGE_REPLICATION_FILTER: | ||
| 5512 | case SQLCOM_XA_START: | ||
| 5513 | case SQLCOM_XA_END: | ||
| 5514 | case SQLCOM_XA_PREPARE: | ||
| 5515 | case SQLCOM_XA_COMMIT: | ||
| 5516 | case SQLCOM_XA_ROLLBACK: | ||
| 5517 | case SQLCOM_XA_RECOVER: | ||
| 5518 | case SQLCOM_INSTALL_PLUGIN: | ||
| 5519 | case SQLCOM_UNINSTALL_PLUGIN: | ||
| 5520 | case SQLCOM_INSTALL_COMPONENT: | ||
| 5521 | case SQLCOM_UNINSTALL_COMPONENT: | ||
| 5522 | case SQLCOM_SHUTDOWN: | ||
| 5523 | case SQLCOM_ALTER_INSTANCE: | ||
| 5524 | case SQLCOM_SELECT: | ||
| 5525 | case SQLCOM_DO: | ||
| 5526 | case SQLCOM_CALL: | ||
| 5527 | case SQLCOM_CREATE_ROLE: | ||
| 5528 | case SQLCOM_DROP_ROLE: | ||
| 5529 | case SQLCOM_SET_ROLE: | ||
| 5530 | case SQLCOM_GRANT_ROLE: | ||
| 5531 | case SQLCOM_REVOKE_ROLE: | ||
| 5532 | case SQLCOM_ALTER_USER_DEFAULT_ROLE: | ||
| 5533 | case SQLCOM_SHOW_BINLOG_EVENTS: | ||
| 5534 | case SQLCOM_SHOW_BINLOGS: | ||
| 5535 | case SQLCOM_SHOW_CHARSETS: | ||
| 5536 | case SQLCOM_SHOW_COLLATIONS: | ||
| 5537 | case SQLCOM_SHOW_CREATE_DB: | ||
| 5538 | case SQLCOM_SHOW_CREATE_EVENT: | ||
| 5539 | case SQLCOM_SHOW_CREATE_FUNC: | ||
| 5540 | case SQLCOM_SHOW_CREATE_PROC: | ||
| 5541 | case SQLCOM_SHOW_CREATE: | ||
| 5542 | case SQLCOM_SHOW_CREATE_TRIGGER: | ||
| 5543 | // case SQLCOM_SHOW_CREATE_USER: | ||
| 5544 | case SQLCOM_SHOW_DATABASES: | ||
| 5545 | case SQLCOM_SHOW_ENGINE_LOGS: | ||
| 5546 | case SQLCOM_SHOW_ENGINE_MUTEX: | ||
| 5547 | case SQLCOM_SHOW_ENGINE_STATUS: | ||
| 5548 | case SQLCOM_SHOW_ERRORS: | ||
| 5549 | case SQLCOM_SHOW_EVENTS: | ||
| 5550 | case SQLCOM_SHOW_FIELDS: | ||
| 5551 | case SQLCOM_SHOW_FUNC_CODE: | ||
| 5552 | case SQLCOM_SHOW_GRANTS: | ||
| 5553 | case SQLCOM_SHOW_KEYS: | ||
| 5554 | case SQLCOM_SHOW_MASTER_STAT: | ||
| 5555 | case SQLCOM_SHOW_OPEN_TABLES: | ||
| 5556 | case SQLCOM_SHOW_PLUGINS: | ||
| 5557 | case SQLCOM_SHOW_PRIVILEGES: | ||
| 5558 | case SQLCOM_SHOW_PROC_CODE: | ||
| 5559 | case SQLCOM_SHOW_PROCESSLIST: | ||
| 5560 | case SQLCOM_SHOW_PROFILE: | ||
| 5561 | case SQLCOM_SHOW_PROFILES: | ||
| 5562 | case SQLCOM_SHOW_RELAYLOG_EVENTS: | ||
| 5563 | case SQLCOM_SHOW_SLAVE_HOSTS: | ||
| 5564 | case SQLCOM_SHOW_SLAVE_STAT: | ||
| 5565 | case SQLCOM_SHOW_STATUS: | ||
| 5566 | case SQLCOM_SHOW_STORAGE_ENGINES: | ||
| 5567 | case SQLCOM_SHOW_TABLE_STATUS: | ||
| 5568 | case SQLCOM_SHOW_TABLES: | ||
| 5569 | case SQLCOM_SHOW_TRIGGERS: | ||
| 5570 | case SQLCOM_SHOW_STATUS_PROC: | ||
| 5571 | case SQLCOM_SHOW_STATUS_FUNC: | ||
| 5572 | case SQLCOM_SHOW_VARIABLES: | ||
| 5573 | case SQLCOM_SHOW_WARNS: | ||
| 5574 | case SQLCOM_SHOW_USER_STATS: | ||
| 5575 | case SQLCOM_SHOW_TABLE_STATS: | ||
| 5576 | case SQLCOM_SHOW_INDEX_STATS: | ||
| 5577 | case SQLCOM_SHOW_CLIENT_STATS: | ||
| 5578 | case SQLCOM_SHOW_THREAD_STATS: | ||
| 5579 | case SQLCOM_CLONE: | ||
| 5580 | case SQLCOM_LOCK_INSTANCE: | ||
| 5581 | case SQLCOM_UNLOCK_INSTANCE: | ||
| 5582 | case SQLCOM_ALTER_TABLESPACE: | ||
| 5583 | case SQLCOM_EXPLAIN_OTHER: | ||
| 5584 | case SQLCOM_RESTART_SERVER: | ||
| 5585 | case SQLCOM_CREATE_SRS: | ||
| 5586 | case SQLCOM_DROP_SRS: { | ||
| 5587 | #ifdef WITH_WSREP | ||
| 5588 |
2/2✓ Branch 0 taken 8396030 times.
✓ Branch 1 taken 1063931 times.
|
9459961 | if (lex->sql_command == SQLCOM_SELECT) |
| 5589 |
14/16✓ Branch 0 taken 8396032 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 120272 times.
✓ Branch 3 taken 8275760 times.
✓ Branch 4 taken 118452 times.
✓ Branch 5 taken 1820 times.
✓ Branch 6 taken 116227 times.
✓ Branch 7 taken 2225 times.
✓ Branch 8 taken 116226 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 116226 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 294 times.
✓ Branch 13 taken 115932 times.
✓ Branch 14 taken 294 times.
✓ Branch 15 taken 8395736 times.
|
8396030 | WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ) |
| 5590 | |||
| 5591 | static std::vector<enum_sql_command> wait_before_show_commands = { | ||
| 5592 | SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_FIELDS, | ||
| 5593 | SQLCOM_SHOW_KEYS, SQLCOM_SHOW_TABLES, | ||
| 5594 | SQLCOM_SHOW_CREATE_PROC, SQLCOM_SHOW_CREATE_FUNC, | ||
| 5595 | SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE, | ||
| 5596 | SQLCOM_SHOW_CREATE_TRIGGER, SQLCOM_SHOW_STATUS, | ||
| 5597 | SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_BINLOGS, | ||
| 5598 | SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CREATE_DB, | ||
| 5599 | SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_STATUS_PROC, | ||
| 5600 | SQLCOM_SHOW_STATUS_FUNC, SQLCOM_SHOW_DATABASES, | ||
| 5601 | SQLCOM_SHOW_TRIGGERS, SQLCOM_SHOW_TABLE_STATUS, | ||
| 5602 | SQLCOM_SHOW_OPEN_TABLES, SQLCOM_SHOW_PLUGINS, | ||
| 5603 | SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_CHARSETS, | ||
| 5604 | SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_STORAGE_ENGINES, | ||
| 5605 | SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_USER_STATS, | ||
| 5606 | SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, | ||
| 5607 |
4/8✓ Branch 0 taken 9394 times.
✓ Branch 1 taken 9450273 times.
✓ Branch 2 taken 9394 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9394 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
9459667 | SQLCOM_SHOW_CLIENT_STATS, SQLCOM_SHOW_THREAD_STATS}; |
| 5608 |
1/2✓ Branch 0 taken 9457779 times.
✗ Branch 1 not taken.
|
9457742 | if (std::find(std::begin(wait_before_show_commands), |
| 5609 | std::end(wait_before_show_commands), | ||
| 5610 |
2/2✓ Branch 0 taken 281984 times.
✓ Branch 1 taken 9175789 times.
|
18917446 | lex->sql_command) != std::end(wait_before_show_commands)) { |
| 5611 |
12/16✓ Branch 0 taken 281984 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15672 times.
✓ Branch 3 taken 266312 times.
✓ Branch 4 taken 15672 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15651 times.
✓ Branch 7 taken 21 times.
✓ Branch 8 taken 15651 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 15651 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 225 times.
✓ Branch 13 taken 15426 times.
✓ Branch 14 taken 225 times.
✓ Branch 15 taken 281759 times.
|
281984 | WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW); |
| 5612 | } | ||
| 5613 | |||
| 5614 |
2/2✓ Branch 0 taken 9456958 times.
✓ Branch 1 taken 590 times.
|
9457548 | if (lex->sql_command == SQLCOM_CREATE_SRS || |
| 5615 |
2/2✓ Branch 0 taken 9456761 times.
✓ Branch 1 taken 197 times.
|
9456958 | lex->sql_command == SQLCOM_DROP_SRS || |
| 5616 |
2/2✓ Branch 0 taken 9456264 times.
✓ Branch 1 taken 497 times.
|
9456761 | lex->sql_command == SQLCOM_INSTALL_COMPONENT || |
| 5617 |
2/2✓ Branch 0 taken 431 times.
✓ Branch 1 taken 9455833 times.
|
9456264 | lex->sql_command == SQLCOM_UNINSTALL_COMPONENT) { |
| 5618 |
8/14✓ Branch 0 taken 1715 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1709 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1715 times.
|
1715 | WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); |
| 5619 | } | ||
| 5620 | |||
| 5621 |
2/2✓ Branch 0 taken 9456549 times.
✓ Branch 1 taken 999 times.
|
9457548 | if (lex->sql_command == SQLCOM_XA_START || |
| 5622 |
2/2✓ Branch 0 taken 9455680 times.
✓ Branch 1 taken 869 times.
|
9456549 | lex->sql_command == SQLCOM_XA_END || |
| 5623 |
2/2✓ Branch 0 taken 9455294 times.
✓ Branch 1 taken 386 times.
|
9455680 | lex->sql_command == SQLCOM_XA_PREPARE || |
| 5624 |
2/2✓ Branch 0 taken 9454678 times.
✓ Branch 1 taken 616 times.
|
9455294 | lex->sql_command == SQLCOM_XA_COMMIT || |
| 5625 |
2/2✓ Branch 0 taken 9454423 times.
✓ Branch 1 taken 255 times.
|
9454678 | lex->sql_command == SQLCOM_XA_ROLLBACK || |
| 5626 |
2/2✓ Branch 0 taken 253 times.
✓ Branch 1 taken 9454170 times.
|
9454423 | lex->sql_command == SQLCOM_XA_RECOVER) { |
| 5627 |
6/8✓ Branch 0 taken 3295 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 3287 times.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
|
3378 | if (WSREP(thd)) { |
| 5628 |
1/26✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
|
8 | WSREP_DEBUG("XA command attempted: %d %s, thd: %u", lex->sql_command, |
| 5629 | thd->query().str, thd->thread_id()); | ||
| 5630 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | my_error(ER_NOT_SUPPORTED_YET, MYF(0), |
| 5631 | "XA with wsrep replication plugin"); | ||
| 5632 | 8 | break; | |
| 5633 | } | ||
| 5634 | } | ||
| 5635 | #endif /* WITH_WSREP */ | ||
| 5636 | |||
| 5637 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9457540 times.
|
9457540 | assert(lex->m_sql_cmd != nullptr); |
| 5638 | |||
| 5639 |
1/2✓ Branch 0 taken 9456721 times.
✗ Branch 1 not taken.
|
9457540 | res = lex->m_sql_cmd->execute(thd); |
| 5640 | |||
| 5641 | 9456721 | break; | |
| 5642 | } | ||
| 5643 | 2543 | case SQLCOM_ALTER_USER: { | |
| 5644 | LEX_USER *user, *tmp_user; | ||
| 5645 | 2543 | bool changing_own_password = false; | |
| 5646 | 2543 | Security_context *sctx = thd->security_context(); | |
| 5647 |
1/2✓ Branch 0 taken 2543 times.
✗ Branch 1 not taken.
|
2543 | bool own_password_expired = sctx->password_expired(); |
| 5648 | 2543 | bool check_permission = true; | |
| 5649 | /* track if it is ALTER USER registration step */ | ||
| 5650 | 2543 | bool finish_reg = false; | |
| 5651 | 2543 | bool init_reg = false; | |
| 5652 | 2543 | bool unregister = false; | |
| 5653 | 2543 | bool is_self = false; | |
| 5654 | |||
| 5655 |
1/2✓ Branch 0 taken 2543 times.
✗ Branch 1 not taken.
|
2543 | List_iterator<LEX_USER> user_list(lex->users_list); |
| 5656 |
2/2✓ Branch 0 taken 2934 times.
✓ Branch 1 taken 2498 times.
|
5432 | while ((tmp_user = user_list++)) { |
| 5657 | LEX_MFA *tmp_lex_mfa; | ||
| 5658 |
1/2✓ Branch 0 taken 2934 times.
✗ Branch 1 not taken.
|
2934 | List_iterator<LEX_MFA> mfa_list_it(tmp_user->mfa_list); |
| 5659 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2934 times.
|
2934 | while ((tmp_lex_mfa = mfa_list_it++)) { |
| 5660 | ✗ | finish_reg |= tmp_lex_mfa->finish_registration; | |
| 5661 | ✗ | init_reg |= tmp_lex_mfa->init_registration; | |
| 5662 | ✗ | unregister |= tmp_lex_mfa->unregister; | |
| 5663 | } | ||
| 5664 | 2934 | bool update_password_only = false; | |
| 5665 | 2934 | bool second_password = false; | |
| 5666 | |||
| 5667 | /* If it is an empty lex_user update it with current user */ | ||
| 5668 |
3/4✓ Branch 0 taken 166 times.
✓ Branch 1 taken 2768 times.
✓ Branch 2 taken 166 times.
✗ Branch 3 not taken.
|
2934 | if (!tmp_user->host.str && !tmp_user->user.str) { |
| 5669 | #ifdef WITH_WSREP | ||
| 5670 |
5/8✓ Branch 0 taken 166 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 162 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
|
166 | if (WSREP(thd)) { |
| 5671 |
13/28✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
4 | WSREP_ERROR( |
| 5672 | "Percona XtraDB Cluster doesn't allow use of" | ||
| 5673 | " CURRENT_USER/USER function for USER operation" | ||
| 5674 | " while operating in cluster mode"); | ||
| 5675 | char message[1024]; | ||
| 5676 | 4 | sprintf(message, | |
| 5677 | "Percona XtraDB Cluster doesn't allow use of" | ||
| 5678 | " CURRENT_USER/USER function for USER operation" | ||
| 5679 | " while operating in cluster mode"); | ||
| 5680 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | my_message(ER_UNKNOWN_ERROR, message, MYF(0)); |
| 5681 | 4 | goto error; | |
| 5682 | } | ||
| 5683 | #endif /* WITH_WSREP */ | ||
| 5684 | |||
| 5685 | /* set user information as of the current user */ | ||
| 5686 |
2/4✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 162 times.
|
162 | assert(sctx->priv_host().str); |
| 5687 |
1/2✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
|
162 | tmp_user->host.str = sctx->priv_host().str; |
| 5688 |
1/2✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
|
162 | tmp_user->host.length = strlen(sctx->priv_host().str); |
| 5689 |
2/4✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 162 times.
|
162 | assert(sctx->user().str); |
| 5690 |
1/2✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
|
162 | tmp_user->user.str = sctx->user().str; |
| 5691 |
1/2✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
|
162 | tmp_user->user.length = strlen(sctx->user().str); |
| 5692 | } | ||
| 5693 |
2/4✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2930 times.
|
2930 | if (!(user = get_current_user(thd, tmp_user))) goto error; |
| 5694 | |||
| 5695 | #ifdef WITH_WSREP | ||
| 5696 | /* When ALTER USER ... IDENTIFIED BY ... REPLACE ... is executed | ||
| 5697 | we need to know the current user to be able to determine REPLACE | ||
| 5698 | clause validity (REPLACE allowed only for the current user's password | ||
| 5699 | change). However ALTER USER is replicated as TOI, so before local | ||
| 5700 | validation/changes. On the slave side, executing thread is wsrep | ||
| 5701 | applier thread and we have no chance to determine if it is OK or not. | ||
| 5702 | Here we do pre-validation for above condition on master size. | ||
| 5703 | Other checks that are not dependent on current user context will be | ||
| 5704 | made made after replication, on slave node */ | ||
| 5705 |
8/10✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 332 times.
✓ Branch 3 taken 2598 times.
✓ Branch 4 taken 332 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 47 times.
✓ Branch 7 taken 285 times.
✓ Branch 8 taken 24 times.
✓ Branch 9 taken 23 times.
|
2930 | if (WSREP(thd) && thd->system_thread == NON_SYSTEM_THREAD) { |
| 5706 | 24 | Security_context *sctx2 = thd->security_context(); | |
| 5707 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | assert(sctx2); |
| 5708 |
2/4✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
|
24 | assert(sctx2->user().str); |
| 5709 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 16 times.
|
24 | if (user->uses_replace_clause) { |
| 5710 | // If trying to set password for other user | ||
| 5711 |
5/6✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 3 times.
|
11 | if (strcmp(sctx2->user().str, user->user.str) || |
| 5712 |
3/6✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
|
3 | my_strcasecmp(system_charset_info, sctx2->priv_host().str, |
| 5713 | user->host.str)) { | ||
| 5714 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | my_error(ER_CURRENT_PASSWORD_NOT_REQUIRED, MYF(0)); |
| 5715 | 5 | goto error; | |
| 5716 | } | ||
| 5717 | } | ||
| 5718 | } | ||
| 5719 | #endif /* WITH_WSREP */ | ||
| 5720 | |||
| 5721 | /* copy password expire attributes to individual lex user */ | ||
| 5722 | 2925 | user->alter_status = thd->lex->alter_password; | |
| 5723 | /* | ||
| 5724 | Only self password change is non-privileged operation. To detect the | ||
| 5725 | same, we find : | ||
| 5726 | (1) If it is only password change operation | ||
| 5727 | (2) If this operation is on self | ||
| 5728 | */ | ||
| 5729 |
2/2✓ Branch 0 taken 1198 times.
✓ Branch 1 taken 1727 times.
|
2925 | if (user->first_factor_auth_info.uses_identified_by_clause && |
| 5730 |
2/2✓ Branch 0 taken 1118 times.
✓ Branch 1 taken 80 times.
|
1198 | !user->first_factor_auth_info.uses_identified_with_clause && |
| 5731 |
2/2✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 30 times.
|
1118 | !thd->lex->mqh.specified_limits && |
| 5732 |
2/2✓ Branch 0 taken 1082 times.
✓ Branch 1 taken 6 times.
|
1088 | !user->alter_status.update_account_locked_column && |
| 5733 |
2/2✓ Branch 0 taken 1081 times.
✓ Branch 1 taken 1 times.
|
1082 | !user->alter_status.update_password_expired_column && |
| 5734 |
2/2✓ Branch 0 taken 1075 times.
✓ Branch 1 taken 6 times.
|
1081 | !user->alter_status.expire_after_days && |
| 5735 |
2/2✓ Branch 0 taken 1072 times.
✓ Branch 1 taken 3 times.
|
1075 | user->alter_status.use_default_password_lifetime && |
| 5736 |
2/2✓ Branch 0 taken 1060 times.
✓ Branch 1 taken 12 times.
|
1072 | (user->alter_status.update_password_require_current == |
| 5737 | 1060 | Lex_acl_attrib_udyn::UNCHANGED) && | |
| 5738 |
1/2✓ Branch 0 taken 1060 times.
✗ Branch 1 not taken.
|
1060 | !user->alter_status.update_password_history && |
| 5739 |
1/2✓ Branch 0 taken 1060 times.
✗ Branch 1 not taken.
|
1060 | !user->alter_status.update_password_reuse_interval && |
| 5740 |
1/2✓ Branch 0 taken 1060 times.
✗ Branch 1 not taken.
|
1060 | !user->alter_status.update_failed_login_attempts && |
| 5741 |
1/2✓ Branch 0 taken 1060 times.
✗ Branch 1 not taken.
|
1060 | !user->alter_status.update_password_lock_time && |
| 5742 |
2/2✓ Branch 0 taken 1059 times.
✓ Branch 1 taken 1 times.
|
1060 | (thd->lex->ssl_type == SSL_TYPE_NOT_SPECIFIED)) |
| 5743 | 1059 | update_password_only = true; | |
| 5744 | |||
| 5745 |
4/6✓ Branch 0 taken 2925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2462 times.
✓ Branch 3 taken 463 times.
✓ Branch 4 taken 2462 times.
✗ Branch 5 not taken.
|
2925 | is_self = !strcmp(sctx->user().length ? sctx->user().str : "", |
| 5746 |
2/2✓ Branch 0 taken 658 times.
✓ Branch 1 taken 2267 times.
|
3583 | user->user.str) && |
| 5747 |
3/6✓ Branch 0 taken 658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 658 times.
✗ Branch 5 not taken.
|
658 | !my_strcasecmp(&my_charset_latin1, user->host.str, |
| 5748 | sctx->priv_host().str); | ||
| 5749 |
2/4✓ Branch 0 taken 2925 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2925 times.
|
2925 | if (finish_reg || init_reg) { |
| 5750 | /* Registration step is allowed only for connecting users */ | ||
| 5751 | ✗ | if (!is_self) { | |
| 5752 | ✗ | my_error(ER_INVALID_USER_FOR_REGISTRATION, MYF(0), sctx->user().str, | |
| 5753 | ✗ | sctx->priv_host().str); | |
| 5754 | ✗ | goto error; | |
| 5755 | } | ||
| 5756 | } | ||
| 5757 | /* | ||
| 5758 | if user executes ALTER statement to change password only | ||
| 5759 | for himself then skip access check - Provided preference to | ||
| 5760 | retain/discard current password was specified. | ||
| 5761 | */ | ||
| 5762 | |||
| 5763 |
4/4✓ Branch 0 taken 2880 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 2835 times.
|
2925 | if (user->discard_old_password || user->retain_current_password) { |
| 5764 | 90 | second_password = true; | |
| 5765 | } | ||
| 5766 |
6/8✓ Branch 0 taken 1866 times.
✓ Branch 1 taken 1059 times.
✓ Branch 2 taken 1821 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 1821 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1821 times.
✗ Branch 7 not taken.
|
2925 | if ((update_password_only || user->discard_old_password || init_reg || |
| 5767 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 1821 times.
✓ Branch 2 taken 314 times.
✓ Branch 3 taken 790 times.
|
2925 | finish_reg || unregister) && |
| 5768 | is_self) { | ||
| 5769 | 314 | changing_own_password = update_password_only; | |
| 5770 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 301 times.
|
314 | if (second_password) { |
| 5771 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | if (check_access(thd, UPDATE_ACL, consts::mysql.c_str(), nullptr, |
| 5772 | 24 | nullptr, true, true) && | |
| 5773 |
11/18✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 12 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 12 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
35 | !sctx->check_access(CREATE_USER_ACL, consts::mysql.c_str()) && |
| 5774 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | !(sctx->has_global_grant( |
| 5775 | STRING_WITH_LEN("APPLICATION_PASSWORD_ADMIN")) | ||
| 5776 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | .first)) { |
| 5777 | ✗ | my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), | |
| 5778 | "CREATE USER or APPLICATION_PASSWORD_ADMIN"); | ||
| 5779 | ✗ | goto error; | |
| 5780 | } | ||
| 5781 | } | ||
| 5782 | 314 | continue; | |
| 5783 |
2/2✓ Branch 0 taken 2230 times.
✓ Branch 1 taken 381 times.
|
2611 | } else if (check_permission) { |
| 5784 |
1/2✓ Branch 0 taken 2230 times.
✗ Branch 1 not taken.
|
2230 | if (check_access(thd, UPDATE_ACL, "mysql", nullptr, nullptr, true, |
| 5785 |
4/4✓ Branch 0 taken 36 times.
✓ Branch 1 taken 2194 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 2214 times.
|
2266 | true) && |
| 5786 |
3/4✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 20 times.
|
36 | check_global_access(thd, CREATE_USER_ACL)) |
| 5787 | 16 | goto error; | |
| 5788 | |||
| 5789 | 2214 | check_permission = false; | |
| 5790 | } | ||
| 5791 | |||
| 5792 |
2/2✓ Branch 0 taken 337 times.
✓ Branch 1 taken 2258 times.
|
2595 | if (is_self && |
| 5793 |
2/2✓ Branch 0 taken 317 times.
✓ Branch 1 taken 20 times.
|
337 | (user->first_factor_auth_info.uses_identified_by_clause || |
| 5794 |
1/2✓ Branch 0 taken 317 times.
✗ Branch 1 not taken.
|
317 | user->first_factor_auth_info.uses_identified_with_clause || |
| 5795 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 317 times.
|
317 | user->first_factor_auth_info.uses_authentication_string_clause)) { |
| 5796 | 20 | changing_own_password = true; | |
| 5797 | 20 | break; | |
| 5798 | } | ||
| 5799 | |||
| 5800 |
2/2✓ Branch 0 taken 743 times.
✓ Branch 1 taken 2 times.
|
745 | if (update_password_only && |
| 5801 |
4/6✓ Branch 0 taken 745 times.
✓ Branch 1 taken 1830 times.
✓ Branch 2 taken 745 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2575 times.
|
3320 | likely((get_server_state() == SERVER_OPERATING)) && |
| 5802 |
2/4✓ Branch 0 taken 743 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 743 times.
|
743 | !strcmp(sctx->priv_user().str, "")) { |
| 5803 | ✗ | my_error(ER_PASSWORD_ANONYMOUS_USER, MYF(0)); | |
| 5804 | ✗ | goto error; | |
| 5805 | } | ||
| 5806 | } | ||
| 5807 | |||
| 5808 |
6/6✓ Branch 0 taken 36 times.
✓ Branch 1 taken 2482 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 2515 times.
|
2518 | if (unlikely(own_password_expired && !changing_own_password)) { |
| 5809 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | my_error(ER_MUST_CHANGE_PASSWORD, MYF(0)); |
| 5810 | 3 | goto error; | |
| 5811 | } | ||
| 5812 | /* Conditionally writes to binlog */ | ||
| 5813 |
1/2✓ Branch 0 taken 2505 times.
✗ Branch 1 not taken.
|
2515 | res = mysql_alter_user(thd, lex->users_list, lex->drop_if_exists); |
| 5814 | /* | ||
| 5815 | Iterate over list of MFA methods, check if all auth plugin methods | ||
| 5816 | which need registration steps have completed, then turn OFF server | ||
| 5817 | sandbox mode | ||
| 5818 | */ | ||
| 5819 | 2505 | tmp_user = lex->users_list[0]; | |
| 5820 |
5/6✓ Branch 0 taken 2191 times.
✓ Branch 1 taken 314 times.
✓ Branch 2 taken 517 times.
✓ Branch 3 taken 1674 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 517 times.
|
2505 | if (!res && is_self && finish_reg) { |
| 5821 | ✗ | if (turn_off_sandbox_mode(thd, tmp_user)) return true; | |
| 5822 | } | ||
| 5823 | 2505 | break; | |
| 5824 | } | ||
| 5825 | ✗ | default: | |
| 5826 | ✗ | assert(0); /* Impossible */ | |
| 5827 | my_ok(thd); | ||
| 5828 | break; | ||
| 5829 | } | ||
| 5830 | 21345987 | goto finish; | |
| 5831 | |||
| 5832 | 17002 | error: | |
| 5833 | #ifdef WITH_WSREP | ||
| 5834 | 17002 | wsrep_error_label: | |
| 5835 | #endif /* WITH_WSREP */ | ||
| 5836 | 17002 | res = true; | |
| 5837 | |||
| 5838 | 21362989 | finish: | |
| 5839 | /* Restore system variables which were changed by SET_VAR hint. */ | ||
| 5840 |
4/4✓ Branch 0 taken 7755 times.
✓ Branch 1 taken 21355234 times.
✓ Branch 2 taken 6736 times.
✓ Branch 3 taken 1019 times.
|
21362989 | if (lex->opt_hints_global && lex->opt_hints_global->sys_var_hint) |
| 5841 |
1/2✓ Branch 0 taken 6736 times.
✗ Branch 1 not taken.
|
6736 | lex->opt_hints_global->sys_var_hint->restore_vars(thd); |
| 5842 | |||
| 5843 |
1/2✓ Branch 0 taken 21363258 times.
✗ Branch 1 not taken.
|
21362989 | THD_STAGE_INFO(thd, stage_query_end); |
| 5844 | |||
| 5845 | // Check for receiving a recent kill signal | ||
| 5846 |
2/2✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 21361914 times.
|
21363258 | if (thd->killed) { |
| 5847 |
1/2✓ Branch 0 taken 754 times.
✗ Branch 1 not taken.
|
1293 | thd->send_kill_message(); |
| 5848 |
1/2✓ Branch 0 taken 754 times.
✗ Branch 1 not taken.
|
754 | res = thd->is_error(); |
| 5849 | } | ||
| 5850 |
2/2✓ Branch 0 taken 151379 times.
✓ Branch 1 taken 21211289 times.
|
21362668 | if (res) { |
| 5851 |
3/4✓ Branch 0 taken 151381 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37720 times.
✓ Branch 3 taken 4810 times.
|
193909 | if (thd->get_reprepare_observer() != nullptr && |
| 5852 |
5/6✓ Branch 0 taken 42531 times.
✓ Branch 1 taken 108850 times.
✓ Branch 2 taken 42530 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37717 times.
✓ Branch 5 taken 113664 times.
|
193912 | thd->get_reprepare_observer()->is_invalidated() && |
| 5853 |
4/6✓ Branch 0 taken 37721 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37721 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37717 times.
✓ Branch 5 taken 4 times.
|
37720 | thd->get_reprepare_observer()->can_retry()) |
| 5854 | 37717 | thd->skip_gtid_rollback = true; | |
| 5855 | } else { | ||
| 5856 | 21211289 | lex->set_exec_started(); | |
| 5857 | } | ||
| 5858 | |||
| 5859 | // Cleanup EXPLAIN info | ||
| 5860 |
2/2✓ Branch 0 taken 21238249 times.
✓ Branch 1 taken 124037 times.
|
21362286 | if (!thd->in_sub_stmt) { |
| 5861 |
3/4✓ Branch 0 taken 21238521 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16566747 times.
✓ Branch 3 taken 4671774 times.
|
21238249 | if (is_explainable_query(lex->sql_command)) { |
| 5862 |
3/4✓ Branch 0 taken 14703542 times.
✓ Branch 1 taken 1863198 times.
✓ Branch 2 taken 14703753 times.
✗ Branch 3 not taken.
|
16566747 | DEBUG_SYNC(thd, "before_reset_query_plan"); |
| 5863 | /* | ||
| 5864 | We want EXPLAIN CONNECTION to work until the explained statement ends, | ||
| 5865 | thus it is only now that we may fully clean up any unit of this | ||
| 5866 | statement. | ||
| 5867 | */ | ||
| 5868 |
1/2✓ Branch 0 taken 16566933 times.
✗ Branch 1 not taken.
|
16566951 | lex->unit->assert_not_fully_clean(); |
| 5869 | } | ||
| 5870 |
1/2✓ Branch 0 taken 21239987 times.
✗ Branch 1 not taken.
|
21238707 | thd->query_plan.set_query_plan(SQLCOM_END, nullptr, false); |
| 5871 | } | ||
| 5872 | |||
| 5873 |
3/4✓ Branch 0 taken 7169096 times.
✓ Branch 1 taken 14194911 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7169041 times.
|
21364024 | assert(!thd->in_active_multi_stmt_transaction() || |
| 5874 | thd->in_multi_stmt_transaction_mode()); | ||
| 5875 | |||
| 5876 |
2/2✓ Branch 0 taken 21239634 times.
✓ Branch 1 taken 124318 times.
|
21363952 | if (!thd->in_sub_stmt) { |
| 5877 |
5/6✓ Branch 0 taken 13648535 times.
✓ Branch 1 taken 7591099 times.
✓ Branch 2 taken 13648536 times.
✓ Branch 3 taken 7591098 times.
✓ Branch 4 taken 21239663 times.
✗ Branch 5 not taken.
|
21239634 | mysql_audit_notify(thd, |
| 5878 | first_level ? MYSQL_AUDIT_QUERY_STATUS_END | ||
| 5879 | : MYSQL_AUDIT_QUERY_NESTED_STATUS_END, | ||
| 5880 | first_level ? "MYSQL_AUDIT_QUERY_STATUS_END" | ||
| 5881 | : "MYSQL_AUDIT_QUERY_NESTED_STATUS_END"); | ||
| 5882 | |||
| 5883 | /* report error issued during command execution */ | ||
| 5884 |
7/8✓ Branch 0 taken 21239805 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 160715 times.
✓ Branch 3 taken 21079090 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 160713 times.
✓ Branch 6 taken 160716 times.
✓ Branch 7 taken 21079089 times.
|
42318755 | if ((thd->is_error() && !early_error_on_rep_command) || |
| 5885 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21079094 times.
|
21079092 | (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR)) |
| 5886 |
1/2✓ Branch 0 taken 160716 times.
✗ Branch 1 not taken.
|
160716 | trans_rollback_stmt(thd); |
| 5887 | else { | ||
| 5888 | /* If commit fails, we should be able to reset the OK status. */ | ||
| 5889 | 21079089 | thd->get_stmt_da()->set_overwrite_status(true); | |
| 5890 |
1/2✓ Branch 0 taken 21078088 times.
✗ Branch 1 not taken.
|
21078847 | trans_commit_stmt(thd); |
| 5891 | 21078088 | thd->get_stmt_da()->set_overwrite_status(false); | |
| 5892 | } | ||
| 5893 | /* | ||
| 5894 | Reset thd killed flag during cleanup so that commands which are | ||
| 5895 | dispatched using service session API's start with a clean state. | ||
| 5896 | */ | ||
| 5897 |
5/6✓ Branch 0 taken 21238432 times.
✓ Branch 1 taken 637 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21238787 times.
✓ Branch 4 taken 616 times.
✓ Branch 5 taken 21238787 times.
|
21239291 | if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_TIMEOUT) { |
| 5898 | 616 | thd->killed = THD::NOT_KILLED; | |
| 5899 |
1/2✓ Branch 0 taken 616 times.
✗ Branch 1 not taken.
|
616 | thd->reset_query_for_display(); |
| 5900 | } | ||
| 5901 | } | ||
| 5902 | |||
| 5903 |
1/2✓ Branch 0 taken 21363170 times.
✗ Branch 1 not taken.
|
21363721 | lex->cleanup(thd, true); |
| 5904 | |||
| 5905 | /* Free tables */ | ||
| 5906 |
1/2✓ Branch 0 taken 21363214 times.
✗ Branch 1 not taken.
|
21363170 | THD_STAGE_INFO(thd, stage_closing_tables); |
| 5907 |
1/2✓ Branch 0 taken 21362775 times.
✗ Branch 1 not taken.
|
21363214 | close_thread_tables(thd); |
| 5908 | |||
| 5909 | // Rollback any item transformations made during optimization and execution | ||
| 5910 |
1/2✓ Branch 0 taken 21363666 times.
✗ Branch 1 not taken.
|
21362775 | thd->rollback_item_tree_changes(); |
| 5911 | |||
| 5912 | #ifndef NDEBUG | ||
| 5913 |
4/4✓ Branch 0 taken 19859200 times.
✓ Branch 1 taken 1504466 times.
✓ Branch 2 taken 19780007 times.
✓ Branch 3 taken 79193 times.
|
21363666 | if (lex->sql_command != SQLCOM_SET_OPTION && !thd->in_sub_stmt) |
| 5914 |
3/4✓ Branch 0 taken 17758966 times.
✓ Branch 1 taken 2019940 times.
✓ Branch 2 taken 17759189 times.
✗ Branch 3 not taken.
|
19780007 | DEBUG_SYNC(thd, "execute_command_after_close_tables"); |
| 5915 | #endif | ||
| 5916 | |||
| 5917 |
12/14✓ Branch 0 taken 21363298 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2904852 times.
✓ Branch 3 taken 18458446 times.
✓ Branch 4 taken 329197 times.
✓ Branch 5 taken 2575655 times.
✓ Branch 6 taken 279432 times.
✓ Branch 7 taken 49765 times.
✓ Branch 8 taken 279173 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 times.
✓ Branch 11 taken 279168 times.
✓ Branch 12 taken 5 times.
✓ Branch 13 taken 21362524 times.
|
21362788 | WSREP_NBO_2ND_PHASE_BEGIN; |
| 5918 | |||
| 5919 |
4/4✓ Branch 0 taken 21238363 times.
✓ Branch 1 taken 124161 times.
✓ Branch 2 taken 479 times.
✓ Branch 3 taken 21237884 times.
|
21362524 | if (!thd->in_sub_stmt && thd->transaction_rollback_request) { |
| 5920 | /* | ||
| 5921 | We are not in sub-statement and transaction rollback was requested by | ||
| 5922 | one of storage engines (e.g. due to deadlock). Rollback transaction in | ||
| 5923 | all storage engines including binary log. | ||
| 5924 | */ | ||
| 5925 |
1/2✓ Branch 0 taken 479 times.
✗ Branch 1 not taken.
|
479 | trans_rollback_implicit(thd); |
| 5926 |
1/2✓ Branch 0 taken 479 times.
✗ Branch 1 not taken.
|
479 | thd->mdl_context.release_transactional_locks(); |
| 5927 |
3/4✓ Branch 0 taken 21362355 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1266742 times.
✓ Branch 3 taken 20095613 times.
|
21362045 | } else if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END)) { |
| 5928 | /* No transaction control allowed in sub-statements. */ | ||
| 5929 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1266742 times.
|
1266742 | assert(!thd->in_sub_stmt); |
| 5930 | /* If commit fails, we should be able to reset the OK status. */ | ||
| 5931 | 1266742 | thd->get_stmt_da()->set_overwrite_status(true); | |
| 5932 | /* Commit the normal transaction if one is active. */ | ||
| 5933 |
1/2✓ Branch 0 taken 1266782 times.
✗ Branch 1 not taken.
|
1266767 | trans_commit_implicit(thd); |
| 5934 | 1266782 | thd->get_stmt_da()->set_overwrite_status(false); | |
| 5935 |
1/2✓ Branch 0 taken 1265888 times.
✗ Branch 1 not taken.
|
1266704 | thd->mdl_context.release_transactional_locks(); |
| 5936 |
6/6✓ Branch 0 taken 19970710 times.
✓ Branch 1 taken 124903 times.
✓ Branch 2 taken 12656887 times.
✓ Branch 3 taken 7314317 times.
✓ Branch 4 taken 12657015 times.
✓ Branch 5 taken 7439092 times.
|
20095613 | } else if (!thd->in_sub_stmt && !thd->in_multi_stmt_transaction_mode()) { |
| 5937 | /* | ||
| 5938 | - If inside a multi-statement transaction, | ||
| 5939 | defer the release of metadata locks until the current | ||
| 5940 | transaction is either committed or rolled back. This prevents | ||
| 5941 | other statements from modifying the table for the entire | ||
| 5942 | duration of this transaction. This provides commit ordering | ||
| 5943 | and guarantees serializability across multiple transactions. | ||
| 5944 | - If in autocommit mode, or outside a transactional context, | ||
| 5945 | automatically release metadata locks of the current statement. | ||
| 5946 | */ | ||
| 5947 |
1/2✓ Branch 0 taken 12658062 times.
✗ Branch 1 not taken.
|
12657015 | thd->mdl_context.release_transactional_locks(); |
| 5948 |
2/2✓ Branch 0 taken 7314325 times.
✓ Branch 1 taken 124767 times.
|
7439092 | } else if (!thd->in_sub_stmt && |
| 5949 |
2/2✓ Branch 0 taken 16012 times.
✓ Branch 1 taken 7298313 times.
|
7314325 | (thd->lex->sql_command != SQLCOM_CREATE_TABLE || |
| 5950 |
2/2✓ Branch 0 taken 15943 times.
✓ Branch 1 taken 69 times.
|
16012 | !thd->lex->create_info->m_transactional_ddl)) { |
| 5951 |
1/2✓ Branch 0 taken 7314575 times.
✗ Branch 1 not taken.
|
7314256 | thd->mdl_context.release_statement_locks(); |
| 5952 | } | ||
| 5953 | |||
| 5954 | #ifdef WITH_WSREP | ||
| 5955 | |||
| 5956 | 21363840 | thd->wsrep_consistency_check = NO_CONSISTENCY_CHECK; | |
| 5957 |
18/24✓ Branch 0 taken 21363840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2904889 times.
✓ Branch 3 taken 18458951 times.
✓ Branch 4 taken 329231 times.
✓ Branch 5 taken 2575658 times.
✓ Branch 6 taken 279454 times.
✓ Branch 7 taken 49777 times.
✓ Branch 8 taken 279439 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 272562 times.
✓ Branch 11 taken 6877 times.
✓ Branch 12 taken 21356964 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 21357117 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 21357088 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 26 times.
✓ Branch 19 taken 21357062 times.
✓ Branch 20 taken 6750 times.
✓ Branch 21 taken 21357062 times.
✓ Branch 22 taken 6407 times.
✗ Branch 23 not taken.
|
21363840 | WSREP_TO_ISOLATION_END; |
| 5958 | |||
| 5959 | /* | ||
| 5960 | Force release of transactional locks if not in active MST and wsrep is on. | ||
| 5961 | */ | ||
| 5962 |
8/8✓ Branch 0 taken 2904886 times.
✓ Branch 1 taken 18459032 times.
✓ Branch 2 taken 329228 times.
✓ Branch 3 taken 2575658 times.
✓ Branch 4 taken 279498 times.
✓ Branch 5 taken 49730 times.
✓ Branch 6 taken 277985 times.
✓ Branch 7 taken 1513 times.
|
21363918 | if (WSREP(thd) && !thd->in_sub_stmt && |
| 5963 |
5/6✓ Branch 0 taken 21363918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 240768 times.
✓ Branch 3 taken 37215 times.
✓ Branch 4 taken 49 times.
✓ Branch 5 taken 21363407 times.
|
42968144 | !thd->in_active_multi_stmt_transaction() && |
| 5964 |
3/4✓ Branch 0 taken 240757 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 240708 times.
|
240768 | thd->mdl_context.has_transactional_locks()) { |
| 5965 |
12/24✓ Branch 0 taken 13 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 13 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 13 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
49 | WSREP_DEBUG("Forcing release of transactional locks for thd %u", |
| 5966 | thd->thread_id()); | ||
| 5967 |
1/2✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
|
49 | thd->mdl_context.release_transactional_locks(); |
| 5968 | } | ||
| 5969 | |||
| 5970 | /* | ||
| 5971 | Current command did not start multi STMT transaction and the command | ||
| 5972 | did not cause commit to happen (e.g. read only). Commit the wsrep | ||
| 5973 | transaction as empty. | ||
| 5974 | */ | ||
| 5975 |
2/2✓ Branch 0 taken 14101956 times.
✓ Branch 1 taken 93958 times.
|
35559370 | if (!thd->in_active_multi_stmt_transaction() && !thd->in_sub_stmt && |
| 5976 |
9/10✓ Branch 0 taken 14195914 times.
✓ Branch 1 taken 7167301 times.
✓ Branch 2 taken 14102066 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 127449 times.
✓ Branch 5 taken 13974617 times.
✓ Branch 6 taken 99591 times.
✓ Branch 7 taken 28018 times.
✓ Branch 8 taken 99591 times.
✓ Branch 9 taken 21263894 times.
|
35686738 | thd->wsrep_trx().active() && |
| 5977 | 127449 | thd->wsrep_trx().state() == wsrep::transaction::s_executing) { | |
| 5978 |
1/2✓ Branch 0 taken 99591 times.
✗ Branch 1 not taken.
|
99591 | wsrep_commit_empty(thd, true); |
| 5979 | } | ||
| 5980 | |||
| 5981 | /* assume PA safety for next transaction */ | ||
| 5982 | 21363485 | thd->wsrep_PA_safe = true; | |
| 5983 | #endif /* WITH_WSREP */ | ||
| 5984 | |||
| 5985 | // If the client wishes to have transaction state reported, we add whatever | ||
| 5986 | // is set on THD to our set here. | ||
| 5987 | { | ||
| 5988 |
1/2✓ Branch 0 taken 21363573 times.
✗ Branch 1 not taken.
|
21363485 | TX_TRACKER_GET(tst); |
| 5989 | |||
| 5990 |
2/2✓ Branch 0 taken 213 times.
✓ Branch 1 taken 21363360 times.
|
21363573 | if (thd->variables.session_track_transaction_info > TX_TRACK_NONE) |
| 5991 |
1/2✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
|
213 | tst->add_trx_state_from_thd(thd); |
| 5992 | |||
| 5993 | // We're done. Clear "is DML" flag. | ||
| 5994 |
1/2✓ Branch 0 taken 21363781 times.
✗ Branch 1 not taken.
|
21363573 | tst->clear_trx_state(thd, TX_STMT_DML); |
| 5995 | } | ||
| 5996 | |||
| 5997 | #ifdef HAVE_LSAN_DO_RECOVERABLE_LEAK_CHECK | ||
| 5998 | // Get incremental leak reports, for easier leak hunting. | ||
| 5999 | // ./mtr --mem --mysqld='-T 4096' --sanitize main.1st | ||
| 6000 | // Don't waste time calling leak sanitizer during bootstrap. | ||
| 6001 | if (!opt_initialize && (test_flags & TEST_DO_QUICK_LEAK_CHECK)) { | ||
| 6002 | int have_leaks = __lsan_do_recoverable_leak_check(); | ||
| 6003 | if (have_leaks > 0) { | ||
| 6004 | fprintf(stderr, "LSAN found leaks for Query: %*s\n", | ||
| 6005 | static_cast<int>(thd->query().length), thd->query().str); | ||
| 6006 | fflush(stderr); | ||
| 6007 | } | ||
| 6008 | } | ||
| 6009 | #endif | ||
| 6010 | |||
| 6011 | #if defined(VALGRIND_DO_QUICK_LEAK_CHECK) | ||
| 6012 | // Get incremental leak reports, for easier leak hunting. | ||
| 6013 | // ./mtr --mem --mysqld='-T 4096' --valgrind-mysqld main.1st | ||
| 6014 | // Note that with multiple connections, the report below may be misleading. | ||
| 6015 | if (test_flags & TEST_DO_QUICK_LEAK_CHECK) { | ||
| 6016 | static unsigned long total_leaked_bytes = 0; | ||
| 6017 | unsigned long leaked = 0; | ||
| 6018 | unsigned long dubious [[maybe_unused]]; | ||
| 6019 | unsigned long reachable [[maybe_unused]]; | ||
| 6020 | unsigned long suppressed [[maybe_unused]]; | ||
| 6021 | /* | ||
| 6022 | We could possibly use VALGRIND_DO_CHANGED_LEAK_CHECK here, | ||
| 6023 | but that is a fairly new addition to the Valgrind api. | ||
| 6024 | Note: we dont want to check 'reachable' until we have done shutdown, | ||
| 6025 | and that is handled by the final report anyways. | ||
| 6026 | We print some extra information, to tell mtr to ignore this report. | ||
| 6027 | */ | ||
| 6028 | LogErr(INFORMATION_LEVEL, ER_VALGRIND_DO_QUICK_LEAK_CHECK); | ||
| 6029 | VALGRIND_DO_QUICK_LEAK_CHECK; | ||
| 6030 | VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed); | ||
| 6031 | if (leaked > total_leaked_bytes) { | ||
| 6032 | LogErr(ERROR_LEVEL, ER_VALGRIND_COUNT_LEAKS, leaked - total_leaked_bytes, | ||
| 6033 | static_cast<int>(thd->query().length), thd->query().str); | ||
| 6034 | } | ||
| 6035 | total_leaked_bytes = leaked; | ||
| 6036 | } | ||
| 6037 | #endif | ||
| 6038 | |||
| 6039 |
7/8✓ Branch 0 taken 21212463 times.
✓ Branch 1 taken 151318 times.
✓ Branch 2 taken 21212544 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21200749 times.
✓ Branch 5 taken 11795 times.
✓ Branch 6 taken 21200742 times.
✓ Branch 7 taken 163120 times.
|
21363781 | if (!res && !thd->is_error()) { // if statement succeeded |
| 6040 |
1/2✓ Branch 0 taken 21200962 times.
✗ Branch 1 not taken.
|
21200742 | binlog_gtid_end_transaction(thd); // finalize GTID life-cycle |
| 6041 |
3/4✓ Branch 0 taken 19123077 times.
✓ Branch 1 taken 2077506 times.
✓ Branch 2 taken 19123336 times.
✗ Branch 3 not taken.
|
21200962 | DEBUG_SYNC(thd, "persist_new_state_after_statement_succeeded"); |
| 6042 |
2/2✓ Branch 0 taken 163087 times.
✓ Branch 1 taken 33 times.
|
163120 | } else if (!gtid_consistency_violation_state && // if the consistency state |
| 6043 |
2/2✓ Branch 0 taken 246 times.
✓ Branch 1 taken 162841 times.
|
163087 | thd->has_gtid_consistency_violation) { // was set by the failing |
| 6044 | // statement | ||
| 6045 |
1/2✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
|
246 | gtid_state->end_gtid_violating_transaction(thd); // just roll it back |
| 6046 |
2/4✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 313 times.
✗ Branch 3 not taken.
|
246 | DEBUG_SYNC(thd, "restore_previous_state_after_statement_failed"); |
| 6047 | } | ||
| 6048 | |||
| 6049 | 21364029 | thd->skip_gtid_rollback = false; | |
| 6050 | |||
| 6051 |
5/6✓ Branch 0 taken 21212676 times.
✓ Branch 1 taken 151353 times.
✓ Branch 2 taken 21212696 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11835 times.
✓ Branch 5 taken 21200861 times.
|
21364029 | return res || thd->is_error(); |
| 6052 | 21390175 | } | |
| 6053 | |||
| 6054 | /** | ||
| 6055 | Do special checking for SHOW statements. | ||
| 6056 | |||
| 6057 | @param thd Thread context. | ||
| 6058 | @param lex LEX for SHOW statement. | ||
| 6059 | @param lock If true, lock metadata for schema objects | ||
| 6060 | |||
| 6061 | @returns false if check is successful, true if error | ||
| 6062 | */ | ||
| 6063 | |||
| 6064 | ✗ | bool show_precheck(THD *thd, LEX *lex, bool lock [[maybe_unused]]) { | |
| 6065 | ✗ | assert(lex->sql_command == SQLCOM_SHOW_CREATE_USER); | |
| 6066 | ✗ | TABLE_LIST *const tables = lex->query_tables; | |
| 6067 | ✗ | if (tables != nullptr) { | |
| 6068 | ✗ | if (check_table_access(thd, SELECT_ACL, tables, false, UINT_MAX, false)) | |
| 6069 | ✗ | return true; | |
| 6070 | } | ||
| 6071 | ✗ | return false; | |
| 6072 | } | ||
| 6073 | |||
| 6074 | #define MY_YACC_INIT 1000 // Start with big alloc | ||
| 6075 | #define MY_YACC_MAX 32000 // Because of 'short' | ||
| 6076 | |||
| 6077 | 4447 | bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, YYLTYPE **yyls, | |
| 6078 | ulong *yystacksize) { | ||
| 6079 | 4447 | Yacc_state *state = ¤t_thd->m_parser_state->m_yacc; | |
| 6080 | 4447 | ulong old_info = 0; | |
| 6081 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
|
4447 | assert(state); |
| 6082 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
|
4447 | if ((uint)*yystacksize >= MY_YACC_MAX) return true; |
| 6083 |
2/2✓ Branch 0 taken 3031 times.
✓ Branch 1 taken 1416 times.
|
4447 | if (!state->yacc_yyvs) old_info = *yystacksize; |
| 6084 | 4447 | *yystacksize = set_zone((*yystacksize) * 2, MY_YACC_INIT, MY_YACC_MAX); | |
| 6085 | 8894 | if (!(state->yacc_yyvs = | |
| 6086 | 8894 | (uchar *)my_realloc(key_memory_bison_stack, state->yacc_yyvs, | |
| 6087 | 4447 | *yystacksize * sizeof(**yyvs), | |
| 6088 | 4447 | MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) || | |
| 6089 | 4447 | !(state->yacc_yyss = | |
| 6090 |
1/2✓ Branch 0 taken 4447 times.
✗ Branch 1 not taken.
|
4447 | (uchar *)my_realloc(key_memory_bison_stack, state->yacc_yyss, |
| 6091 | 4447 | *yystacksize * sizeof(**yyss), | |
| 6092 |
2/4✓ Branch 0 taken 4447 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4447 times.
|
8894 | MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) || |
| 6093 | 4447 | !(state->yacc_yyls = | |
| 6094 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
|
4447 | (uchar *)my_realloc(key_memory_bison_stack, state->yacc_yyls, |
| 6095 | 4447 | *yystacksize * sizeof(**yyls), | |
| 6096 | MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR)))) | ||
| 6097 | ✗ | return true; | |
| 6098 |
2/2✓ Branch 0 taken 3031 times.
✓ Branch 1 taken 1416 times.
|
4447 | if (old_info) { |
| 6099 | /* | ||
| 6100 | Only copy the old stack on the first call to my_yyoverflow(), | ||
| 6101 | when replacing a static stack (YYINITDEPTH) by a dynamic stack. | ||
| 6102 | For subsequent calls, my_realloc already did preserve the old stack. | ||
| 6103 | */ | ||
| 6104 | 3031 | memcpy(state->yacc_yyss, *yyss, old_info * sizeof(**yyss)); | |
| 6105 | 3031 | memcpy(state->yacc_yyvs, *yyvs, old_info * sizeof(**yyvs)); | |
| 6106 | 3031 | memcpy(state->yacc_yyls, *yyls, old_info * sizeof(**yyls)); | |
| 6107 | } | ||
| 6108 | 4447 | *yyss = (short *)state->yacc_yyss; | |
| 6109 | 4447 | *yyvs = (YYSTYPE *)state->yacc_yyvs; | |
| 6110 | 4447 | *yyls = (YYLTYPE *)state->yacc_yyls; | |
| 6111 | 4447 | return false; | |
| 6112 | } | ||
| 6113 | |||
| 6114 | /** | ||
| 6115 | Reset the part of THD responsible for the state of command | ||
| 6116 | processing. | ||
| 6117 | |||
| 6118 | This needs to be called before execution of every statement | ||
| 6119 | (prepared or conventional). It is not called by substatements of | ||
| 6120 | routines. | ||
| 6121 | |||
| 6122 | @todo Remove mysql_reset_thd_for_next_command and only use the | ||
| 6123 | member function. | ||
| 6124 | |||
| 6125 | @todo Call it after we use THD for queries, not before. | ||
| 6126 | */ | ||
| 6127 | 14626142 | void mysql_reset_thd_for_next_command(THD *thd) { | |
| 6128 | 14626142 | thd->reset_for_next_command(); | |
| 6129 | 14627340 | } | |
| 6130 | |||
| 6131 | 14792479 | void THD::reset_for_next_command() { | |
| 6132 | // TODO: Why on earth is this here?! We should probably fix this | ||
| 6133 | // function and move it to the proper file. /Matz | ||
| 6134 | 14792479 | THD *thd = this; | |
| 6135 |
1/2✓ Branch 0 taken 14793526 times.
✗ Branch 1 not taken.
|
14792479 | DBUG_TRACE; |
| 6136 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14793526 times.
|
14793526 | assert(!thd->sp_runtime_ctx); /* not for substatements of routines */ |
| 6137 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14793526 times.
|
14793526 | assert(!thd->in_sub_stmt); |
| 6138 | 14793526 | thd->reset_item_list(); | |
| 6139 | /* | ||
| 6140 | Those two lines below are theoretically unneeded as | ||
| 6141 | THD::cleanup_after_query() should take care of this already. | ||
| 6142 | */ | ||
| 6143 | 14792791 | thd->auto_inc_intervals_in_cur_stmt_for_binlog.clear(); | |
| 6144 | 14793115 | thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt = false; | |
| 6145 | |||
| 6146 | #ifdef WITH_WSREP | ||
| 6147 | /* | ||
| 6148 | Autoinc variables should be adjusted only for locally executed | ||
| 6149 | transactions. Appliers and replayers are either processing ROW | ||
| 6150 | events or get autoinc variable values from Query_log_event and | ||
| 6151 | mysql slave may be processing STATEMENT format events, but it should | ||
| 6152 | use autoinc values passed in binlog events, not the values forced by | ||
| 6153 | the cluster. | ||
| 6154 | */ | ||
| 6155 |
16/18✓ Branch 0 taken 14793175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 443544 times.
✓ Branch 3 taken 14349631 times.
✓ Branch 4 taken 377793 times.
✓ Branch 5 taken 65751 times.
✓ Branch 6 taken 361559 times.
✓ Branch 7 taken 16234 times.
✓ Branch 8 taken 361565 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 191810 times.
✓ Branch 11 taken 169755 times.
✓ Branch 12 taken 190077 times.
✓ Branch 13 taken 1733 times.
✓ Branch 14 taken 190028 times.
✓ Branch 15 taken 49 times.
✓ Branch 16 taken 190028 times.
✓ Branch 17 taken 14603093 times.
|
14793115 | if (WSREP(thd) && wsrep_thd_is_local(thd) && !thd->slave_thread && |
| 6156 | wsrep_auto_increment_control) { | ||
| 6157 | 190028 | thd->variables.auto_increment_offset = | |
| 6158 | 190028 | global_system_variables.auto_increment_offset; | |
| 6159 | 190028 | thd->variables.auto_increment_increment = | |
| 6160 | 190028 | global_system_variables.auto_increment_increment; | |
| 6161 | } | ||
| 6162 | #endif /* WITH_WSREP */ | ||
| 6163 | |||
| 6164 | 14793121 | thd->query_start_usec_used = false; | |
| 6165 | 14793121 | thd->m_is_fatal_error = false; | |
| 6166 | 14793121 | thd->time_zone_used = false; | |
| 6167 | /* | ||
| 6168 | Clear the status flag that are expected to be cleared at the | ||
| 6169 | beginning of each SQL statement. | ||
| 6170 | */ | ||
| 6171 | 14793121 | thd->server_status &= ~SERVER_STATUS_CLEAR_SET; | |
| 6172 | /* | ||
| 6173 | If in autocommit mode and not in a transaction, reset flag | ||
| 6174 | that identifies if a transaction has done some operations | ||
| 6175 | that cannot be safely rolled back. | ||
| 6176 | |||
| 6177 | If the flag is set an warning message is printed out in | ||
| 6178 | ha_rollback_trans() saying that some tables couldn't be | ||
| 6179 | rolled back. | ||
| 6180 | */ | ||
| 6181 |
2/2✓ Branch 0 taken 11261158 times.
✓ Branch 1 taken 3531765 times.
|
14793121 | if (!thd->in_multi_stmt_transaction_mode()) { |
| 6182 |
1/2✓ Branch 0 taken 11261144 times.
✗ Branch 1 not taken.
|
11261158 | thd->get_transaction()->reset_unsafe_rollback_flags( |
| 6183 | Transaction_ctx::SESSION); | ||
| 6184 | } | ||
| 6185 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14793189 times.
|
14792909 | assert(thd->security_context() == &thd->m_main_security_ctx); |
| 6186 | 14793189 | thd->thread_specific_used = false; | |
| 6187 | |||
| 6188 |
2/2✓ Branch 0 taken 12780961 times.
✓ Branch 1 taken 2012228 times.
|
14793189 | if (opt_bin_log) { |
| 6189 |
1/2✓ Branch 0 taken 12780612 times.
✗ Branch 1 not taken.
|
12780961 | thd->user_var_events.clear(); |
| 6190 | 12780612 | thd->user_var_events_alloc = thd->mem_root; | |
| 6191 | } | ||
| 6192 |
1/2✓ Branch 0 taken 14793652 times.
✗ Branch 1 not taken.
|
14792840 | thd->clear_error(); |
| 6193 |
1/2✓ Branch 0 taken 14793675 times.
✗ Branch 1 not taken.
|
14793652 | thd->get_stmt_da()->reset_diagnostics_area(); |
| 6194 | 14793675 | thd->get_stmt_da()->reset_statement_cond_count(); | |
| 6195 | |||
| 6196 | 14793147 | thd->rand_used = false; | |
| 6197 | |||
| 6198 | 14793147 | thd->clear_slow_extended(); | |
| 6199 | |||
| 6200 |
1/2✓ Branch 0 taken 14793689 times.
✗ Branch 1 not taken.
|
14793652 | thd->reset_current_stmt_binlog_format_row(); |
| 6201 | 14793689 | thd->binlog_unsafe_warning_flags = 0; | |
| 6202 | 14793689 | thd->binlog_need_explicit_defaults_ts = false; | |
| 6203 | |||
| 6204 | 14793689 | thd->commit_error = THD::CE_NONE; | |
| 6205 | 14793689 | thd->durability_property = HA_REGULAR_DURABILITY; | |
| 6206 |
1/2✓ Branch 0 taken 14793646 times.
✗ Branch 1 not taken.
|
14793689 | thd->set_trans_pos(nullptr, 0); |
| 6207 | 14793646 | thd->derived_tables_processing = false; | |
| 6208 | 14793646 | thd->parsing_system_view = false; | |
| 6209 | |||
| 6210 | // Need explicit setting, else demand all privileges to a table. | ||
| 6211 | 14793646 | thd->want_privilege = ~NO_ACCESS; | |
| 6212 | |||
| 6213 | 14793646 | thd->reset_skip_readonly_check(); | |
| 6214 | 14792884 | thd->tx_commit_pending = false; | |
| 6215 | |||
| 6216 |
5/8✓ Branch 0 taken 14793254 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14793346 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 197 times.
✓ Branch 5 taken 14793149 times.
✓ Branch 6 taken 197 times.
✗ Branch 7 not taken.
|
14792884 | DBUG_PRINT("debug", ("is_current_stmt_binlog_format_row(): %d", |
| 6217 | thd->is_current_stmt_binlog_format_row())); | ||
| 6218 | |||
| 6219 | /* | ||
| 6220 | In case we're processing multiple statements we need to checkout a new | ||
| 6221 | acl access map here as the global acl version might have increased due to | ||
| 6222 | a grant/revoke or flush. | ||
| 6223 | */ | ||
| 6224 |
1/2✓ Branch 0 taken 14793191 times.
✗ Branch 1 not taken.
|
14793346 | thd->security_context()->checkout_access_maps(); |
| 6225 | #ifndef NDEBUG | ||
| 6226 | 14793191 | thd->set_tmp_table_seq_id(1); | |
| 6227 | #endif | ||
| 6228 | 14792928 | } | |
| 6229 | |||
| 6230 | /* | ||
| 6231 | When you modify dispatch_sql_command(), you may need to modify | ||
| 6232 | mysql_test_parse_for_slave() in this same file. | ||
| 6233 | */ | ||
| 6234 | |||
| 6235 | /** | ||
| 6236 | Parse an SQL command from a text string and pass the resulting AST to the | ||
| 6237 | query executor. | ||
| 6238 | |||
| 6239 | @param thd Current session. | ||
| 6240 | @param parser_state Parser state. | ||
| 6241 | */ | ||
| 6242 | |||
| 6243 | 13554440 | void dispatch_sql_command(THD *thd, Parser_state *parser_state, | |
| 6244 | bool update_userstat) { | ||
| 6245 |
1/2✓ Branch 0 taken 13555566 times.
✗ Branch 1 not taken.
|
13554440 | DBUG_TRACE; |
| 6246 |
6/10✓ Branch 0 taken 13555096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13555486 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 180 times.
✓ Branch 5 taken 13555306 times.
✓ Branch 6 taken 180 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 180 times.
✗ Branch 9 not taken.
|
13555566 | DBUG_PRINT("dispatch_sql_command", ("query: '%s'", thd->query().str)); |
| 6247 | |||
| 6248 |
2/6✓ Branch 0 taken 13555345 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13555345 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
13555486 | DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on();); |
| 6249 | |||
| 6250 |
1/2✓ Branch 0 taken 13555657 times.
✗ Branch 1 not taken.
|
13555345 | mysql_reset_thd_for_next_command(thd); |
| 6251 |
1/2✓ Branch 0 taken 13555165 times.
✗ Branch 1 not taken.
|
13555657 | lex_start(thd); |
| 6252 | |||
| 6253 | /* Declare userstat variables and start timer */ | ||
| 6254 | 13555165 | double start_busy_usecs = 0.0; | |
| 6255 | 13555165 | double start_cpu_nsecs = 0.0; | |
| 6256 |
6/6✓ Branch 0 taken 11129 times.
✓ Branch 1 taken 13544036 times.
✓ Branch 2 taken 9454 times.
✓ Branch 3 taken 1675 times.
✓ Branch 4 taken 9454 times.
✓ Branch 5 taken 13545696 times.
|
13555165 | if (unlikely(opt_userstat && update_userstat)) |
| 6257 | 9454 | userstat_start_timer(&start_busy_usecs, &start_cpu_nsecs); | |
| 6258 | |||
| 6259 | 13555150 | thd->m_parser_state = parser_state; | |
| 6260 |
1/2✓ Branch 0 taken 13554911 times.
✗ Branch 1 not taken.
|
13555150 | invoke_pre_parse_rewrite_plugins(thd); |
| 6261 | 13554911 | thd->m_parser_state = nullptr; | |
| 6262 | |||
| 6263 | // we produce digest if it's not explicitly turned off | ||
| 6264 | // by setting maximum digest length to zero | ||
| 6265 |
2/4✓ Branch 0 taken 13554256 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13554289 times.
✗ Branch 3 not taken.
|
13554911 | if (get_max_digest_length() != 0) |
| 6266 | 13554289 | parser_state->m_input.m_compute_digest = true; | |
| 6267 | |||
| 6268 | 13554256 | LEX *lex = thd->lex; | |
| 6269 | 13554256 | const char *found_semicolon = nullptr; | |
| 6270 | |||
| 6271 | 13554256 | bool err = thd->get_stmt_da()->is_error(); | |
| 6272 | |||
| 6273 |
1/2✓ Branch 0 taken 13554953 times.
✗ Branch 1 not taken.
|
13554944 | if (!err) { |
| 6274 |
1/2✓ Branch 0 taken 13555152 times.
✗ Branch 1 not taken.
|
13554953 | err = parse_sql(thd, parser_state, nullptr); |
| 6275 |
3/4✓ Branch 0 taken 13547447 times.
✓ Branch 1 taken 7705 times.
✓ Branch 2 taken 13546976 times.
✗ Branch 3 not taken.
|
13555152 | if (!err) err = invoke_post_parse_rewrite_plugins(thd, false); |
| 6276 | |||
| 6277 | 13554681 | found_semicolon = parser_state->m_lip.found_semicolon; | |
| 6278 | } | ||
| 6279 | |||
| 6280 |
3/4✓ Branch 0 taken 11682583 times.
✓ Branch 1 taken 1872089 times.
✓ Branch 2 taken 11683288 times.
✗ Branch 3 not taken.
|
13554672 | DEBUG_SYNC_C("sql_parse_before_rewrite"); |
| 6281 | |||
| 6282 |
2/2✓ Branch 0 taken 13548134 times.
✓ Branch 1 taken 7243 times.
|
13555377 | if (!err) { |
| 6283 | /* | ||
| 6284 | Rewrite the query for logging and for the Performance Schema | ||
| 6285 | statement tables. (Raw logging happened earlier.) | ||
| 6286 | |||
| 6287 | Sub-routines of mysql_rewrite_query() should try to only rewrite when | ||
| 6288 | necessary (e.g. not do password obfuscation when query contains no | ||
| 6289 | password). | ||
| 6290 | |||
| 6291 | If rewriting does not happen here, thd->m_rewritten_query is still | ||
| 6292 | empty from being reset in alloc_query(). | ||
| 6293 | */ | ||
| 6294 |
4/6✓ Branch 0 taken 13547644 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11722663 times.
✓ Branch 3 taken 1824921 times.
✓ Branch 4 taken 11722216 times.
✗ Branch 5 not taken.
|
13548134 | if (thd->rewritten_query().length() == 0) mysql_rewrite_query(thd); |
| 6295 | |||
| 6296 |
3/4✓ Branch 0 taken 13547725 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1839503 times.
✓ Branch 3 taken 11708331 times.
|
13547137 | if (thd->rewritten_query().length()) { |
| 6297 | 1839503 | lex->safe_to_cache_query = false; // see comments below | |
| 6298 | |||
| 6299 |
2/4✓ Branch 0 taken 1838470 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1838511 times.
✗ Branch 3 not taken.
|
1838470 | thd->set_query_for_display(thd->rewritten_query().ptr(), |
| 6300 |
1/2✓ Branch 0 taken 1838470 times.
✗ Branch 1 not taken.
|
1839503 | thd->rewritten_query().length()); |
| 6301 |
2/2✓ Branch 0 taken 523153 times.
✓ Branch 1 taken 11185178 times.
|
11708331 | } else if (thd->slave_thread) { |
| 6302 | /* | ||
| 6303 | In the slave, we add the information to pfs.events_statements_history, | ||
| 6304 | but not to pfs.threads, as that is what the test suite expects. | ||
| 6305 | */ | ||
| 6306 |
3/6✓ Branch 0 taken 523146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 523375 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 523255 times.
✗ Branch 5 not taken.
|
523153 | MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query().str, |
| 6307 | thd->query().length); | ||
| 6308 | } else { | ||
| 6309 |
3/6✓ Branch 0 taken 11185553 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11185744 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11186380 times.
✗ Branch 5 not taken.
|
11185178 | thd->set_query_for_display(thd->query().str, thd->query().length); |
| 6310 | } | ||
| 6311 | |||
| 6312 |
4/4✓ Branch 0 taken 13547908 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 13024648 times.
✓ Branch 3 taken 523260 times.
|
13548146 | if (!(opt_general_log_raw || thd->slave_thread)) { |
| 6313 |
3/4✓ Branch 0 taken 13024520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1839082 times.
✓ Branch 3 taken 11185447 times.
|
13024648 | if (thd->rewritten_query().length()) |
| 6314 |
1/2✓ Branch 0 taken 1838334 times.
✗ Branch 1 not taken.
|
1838459 | query_logger.general_log_write(thd, COM_QUERY, |
| 6315 |
1/2✓ Branch 0 taken 1838459 times.
✗ Branch 1 not taken.
|
1838459 | thd->rewritten_query().ptr(), |
| 6316 |
1/2✓ Branch 0 taken 1838459 times.
✗ Branch 1 not taken.
|
1839082 | thd->rewritten_query().length()); |
| 6317 | else { | ||
| 6318 |
3/4✓ Branch 0 taken 80935 times.
✓ Branch 1 taken 11104512 times.
✓ Branch 2 taken 80935 times.
✗ Branch 3 not taken.
|
11185447 | size_t qlen = found_semicolon ? (found_semicolon - thd->query().str) |
| 6319 |
1/2✓ Branch 0 taken 11104889 times.
✗ Branch 1 not taken.
|
11104512 | : thd->query().length; |
| 6320 | |||
| 6321 |
2/4✓ Branch 0 taken 11185735 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11186074 times.
✗ Branch 3 not taken.
|
11185824 | query_logger.general_log_write(thd, COM_QUERY, thd->query().str, qlen); |
| 6322 | } | ||
| 6323 | } | ||
| 6324 | } | ||
| 6325 | |||
| 6326 |
3/4✓ Branch 0 taken 11683048 times.
✓ Branch 1 taken 1872101 times.
✓ Branch 2 taken 11683610 times.
✗ Branch 3 not taken.
|
13555149 | DEBUG_SYNC_C("sql_parse_after_rewrite"); |
| 6327 | |||
| 6328 |
2/2✓ Branch 0 taken 13548420 times.
✓ Branch 1 taken 7291 times.
|
13555711 | if (!err) { |
| 6329 |
1/2✓ Branch 0 taken 13548224 times.
✗ Branch 1 not taken.
|
13548420 | thd->m_statement_psi = MYSQL_REFINE_STATEMENT( |
| 6330 | thd->m_statement_psi, sql_statement_info[thd->lex->sql_command].m_key); | ||
| 6331 | |||
| 6332 |
6/6✓ Branch 0 taken 77878 times.
✓ Branch 1 taken 13470346 times.
✓ Branch 2 taken 304 times.
✓ Branch 3 taken 77574 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 13548199 times.
|
13548507 | if (mqh_used && thd->get_user_connect() && |
| 6333 |
3/4✓ Branch 0 taken 283 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 279 times.
|
304 | check_mqh(thd, lex->sql_command)) { |
| 6334 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | if (thd->is_classic_protocol()) |
| 6335 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | thd->get_protocol_classic()->get_net()->error = NET_ERROR_UNSET; |
| 6336 | } else { | ||
| 6337 |
3/4✓ Branch 0 taken 13548264 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13548246 times.
✓ Branch 3 taken 18 times.
|
13548199 | if (!thd->is_error()) { |
| 6338 | /* | ||
| 6339 | Binlog logs a string starting from thd->query and having length | ||
| 6340 | thd->query_length; so we set thd->query_length correctly (to not | ||
| 6341 | log several statements in one event, when we executed only first). | ||
| 6342 | We set it to not see the ';' (otherwise it would get into binlog | ||
| 6343 | and Query_log_event::print() would give ';;' output). | ||
| 6344 | This also helps display only the current query in SHOW | ||
| 6345 | PROCESSLIST. | ||
| 6346 | */ | ||
| 6347 |
6/8✓ Branch 0 taken 80951 times.
✓ Branch 1 taken 13467295 times.
✓ Branch 2 taken 80951 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80951 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80951 times.
✓ Branch 7 taken 13467295 times.
|
13548246 | if (found_semicolon && (ulong)(found_semicolon - thd->query().str)) |
| 6348 | 242853 | thd->set_query( | |
| 6349 |
1/2✓ Branch 0 taken 80951 times.
✗ Branch 1 not taken.
|
80951 | thd->query().str, |
| 6350 |
2/4✓ Branch 0 taken 80951 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80951 times.
✗ Branch 3 not taken.
|
80951 | static_cast<size_t>(found_semicolon - thd->query().str - 1)); |
| 6351 | /* Actually execute the query */ | ||
| 6352 |
2/2✓ Branch 0 taken 80951 times.
✓ Branch 1 taken 13467295 times.
|
13548246 | if (found_semicolon) { |
| 6353 | 80951 | lex->safe_to_cache_query = false; | |
| 6354 | 80951 | thd->server_status |= SERVER_MORE_RESULTS_EXISTS; | |
| 6355 | } | ||
| 6356 |
1/2✓ Branch 0 taken 13547256 times.
✗ Branch 1 not taken.
|
13548246 | lex->set_trg_event_type_for_tables(); |
| 6357 | |||
| 6358 | int error [[maybe_unused]]; | ||
| 6359 |
2/2✓ Branch 0 taken 124 times.
✓ Branch 1 taken 13547491 times.
|
13547481 | if (unlikely( |
| 6360 |
1/2✓ Branch 0 taken 13547642 times.
✗ Branch 1 not taken.
|
13547256 | (thd->security_context()->password_expired() || |
| 6361 |
2/4✓ Branch 0 taken 13547314 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13547314 times.
|
13547475 | thd->security_context()->is_in_registration_sandbox_mode()) && |
| 6362 |
4/4✓ Branch 0 taken 13547475 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 7 times.
|
27095116 | lex->sql_command != SQLCOM_SET_PASSWORD && |
| 6363 |
2/2✓ Branch 0 taken 124 times.
✓ Branch 1 taken 36 times.
|
160 | lex->sql_command != SQLCOM_ALTER_USER)) { |
| 6364 |
2/4✓ Branch 0 taken 124 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 124 times.
|
124 | if (thd->security_context()->is_in_registration_sandbox_mode()) |
| 6365 | ✗ | my_error(ER_PLUGIN_REQUIRES_REGISTRATION, MYF(0)); | |
| 6366 | else | ||
| 6367 |
1/2✓ Branch 0 taken 124 times.
✗ Branch 1 not taken.
|
124 | my_error(ER_MUST_CHANGE_PASSWORD, MYF(0)); |
| 6368 | 124 | error = 1; | |
| 6369 | } else { | ||
| 6370 | 13547491 | resourcegroups::Resource_group *src_res_grp = nullptr; | |
| 6371 | 13547491 | resourcegroups::Resource_group *dest_res_grp = nullptr; | |
| 6372 | 13547491 | MDL_ticket *ticket = nullptr; | |
| 6373 | 13547491 | MDL_ticket *cur_ticket = nullptr; | |
| 6374 |
1/2✓ Branch 0 taken 13547654 times.
✗ Branch 1 not taken.
|
13547491 | auto mgr_ptr = resourcegroups::Resource_group_mgr::instance(); |
| 6375 |
1/2✓ Branch 0 taken 13547217 times.
✗ Branch 1 not taken.
|
13547654 | bool switched = mgr_ptr->switch_resource_group_if_needed( |
| 6376 | thd, &src_res_grp, &dest_res_grp, &ticket, &cur_ticket); | ||
| 6377 | |||
| 6378 |
1/2✓ Branch 0 taken 13546155 times.
✗ Branch 1 not taken.
|
13547217 | error = mysql_execute_command(thd, true); |
| 6379 | |||
| 6380 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 13546151 times.
|
13546155 | if (switched) |
| 6381 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | mgr_ptr->restore_original_resource_group(thd, src_res_grp, |
| 6382 | dest_res_grp); | ||
| 6383 | 13546155 | thd->resource_group_ctx()->m_switch_resource_group_str[0] = '\0'; | |
| 6384 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 13546056 times.
|
13546066 | if (ticket != nullptr) |
| 6385 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | mgr_ptr->release_shared_mdl_for_resource_group(thd, ticket); |
| 6386 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13546064 times.
|
13546066 | if (cur_ticket != nullptr) |
| 6387 |
0/2✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
2 | mgr_ptr->release_shared_mdl_for_resource_group(thd, cur_ticket); |
| 6388 | } | ||
| 6389 | } | ||
| 6390 | } | ||
| 6391 | } else { | ||
| 6392 | /* | ||
| 6393 | Log the failed raw query in the Performance Schema. This statement did | ||
| 6394 | not parse, so there is no way to tell if it may contain a password of not. | ||
| 6395 | |||
| 6396 | The tradeoff is: | ||
| 6397 | a) If we do log the query, a user typing by accident a broken query | ||
| 6398 | containing a password will have the password exposed. This is very | ||
| 6399 | unlikely, and this behavior can be documented. Remediation is to use | ||
| 6400 | a new password when retyping the corrected query. | ||
| 6401 | |||
| 6402 | b) If we do not log the query, finding broken queries in the client | ||
| 6403 | application will be much more difficult. This is much more likely. | ||
| 6404 | |||
| 6405 | Considering that broken queries can typically be generated by attempts at | ||
| 6406 | SQL injection, finding the source of the SQL injection is critical, so the | ||
| 6407 | design choice is to log the query text of broken queries (a). | ||
| 6408 | */ | ||
| 6409 |
3/6✓ Branch 0 taken 7291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7291 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7291 times.
✗ Branch 5 not taken.
|
7291 | thd->set_query_for_display(thd->query().str, thd->query().length); |
| 6410 | |||
| 6411 | /* Instrument this broken statement as "statement/sql/error" */ | ||
| 6412 |
1/2✓ Branch 0 taken 7291 times.
✗ Branch 1 not taken.
|
7291 | thd->m_statement_psi = MYSQL_REFINE_STATEMENT( |
| 6413 | thd->m_statement_psi, sql_statement_info[SQLCOM_END].m_key); | ||
| 6414 | |||
| 6415 |
2/4✓ Branch 0 taken 7291 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7291 times.
|
7291 | assert(thd->is_error()); |
| 6416 |
3/8✓ Branch 0 taken 7291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7291 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7291 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
7291 | DBUG_PRINT("info", |
| 6417 | ("Command aborted. Fatal_error: %d", thd->is_fatal_error())); | ||
| 6418 | } | ||
| 6419 | |||
| 6420 |
1/2✓ Branch 0 taken 13553669 times.
✗ Branch 1 not taken.
|
13553472 | THD_STAGE_INFO(thd, stage_freeing_items); |
| 6421 |
1/2✓ Branch 0 taken 13553174 times.
✗ Branch 1 not taken.
|
13553669 | sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); |
| 6422 |
1/2✓ Branch 0 taken 13553566 times.
✗ Branch 1 not taken.
|
13553174 | sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); |
| 6423 |
1/2✓ Branch 0 taken 13553547 times.
✗ Branch 1 not taken.
|
13553566 | thd->lex->destroy(); |
| 6424 |
1/2✓ Branch 0 taken 13553756 times.
✗ Branch 1 not taken.
|
13553547 | thd->end_statement(); |
| 6425 |
1/2✓ Branch 0 taken 13553755 times.
✗ Branch 1 not taken.
|
13553756 | thd->cleanup_after_query(); |
| 6426 |
2/2✓ Branch 0 taken 176 times.
✓ Branch 1 taken 13553352 times.
|
13553755 | assert(thd->change_list.is_empty()); |
| 6427 | |||
| 6428 | /* Update user statistics only if at least one timer was initialized */ | ||
| 6429 |
4/4✓ Branch 0 taken 2421062 times.
✓ Branch 1 taken 11132290 times.
✓ Branch 2 taken 9454 times.
✓ Branch 3 taken 13544075 times.
|
15974414 | if (unlikely(update_userstat && |
| 6430 |
4/4✓ Branch 0 taken 2411663 times.
✓ Branch 1 taken 9399 times.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 2411608 times.
|
2421062 | (start_busy_usecs > 0.0 || start_cpu_nsecs > 0.0))) { |
| 6431 | 9454 | userstat_finish_timer(start_busy_usecs, start_cpu_nsecs, &thd->busy_time, | |
| 6432 | &thd->cpu_time); | ||
| 6433 | /* Updates THD stats and the global user stats. */ | ||
| 6434 | 9454 | thd->update_stats(true); | |
| 6435 |
1/2✓ Branch 0 taken 9454 times.
✗ Branch 1 not taken.
|
9454 | update_global_user_stats(thd, true, my_getsystime()); |
| 6436 | } | ||
| 6437 | |||
| 6438 |
3/4✓ Branch 0 taken 11681359 times.
✓ Branch 1 taken 1872117 times.
✓ Branch 2 taken 11682017 times.
✗ Branch 3 not taken.
|
13553529 | DEBUG_SYNC(thd, "query_rewritten"); |
| 6439 | 13554134 | } | |
| 6440 | |||
| 6441 | /** | ||
| 6442 | Usable by the replication SQL thread only: just parse a query to know if it | ||
| 6443 | can be ignored because of replicate-*-table rules. | ||
| 6444 | |||
| 6445 | @retval | ||
| 6446 | 0 cannot be ignored | ||
| 6447 | @retval | ||
| 6448 | 1 can be ignored | ||
| 6449 | */ | ||
| 6450 | |||
| 6451 | 5 | bool mysql_test_parse_for_slave(THD *thd) { | |
| 6452 | 5 | LEX *lex = thd->lex; | |
| 6453 | 5 | bool ignorable = false; | |
| 6454 | 5 | sql_digest_state *parent_digest = thd->m_digest; | |
| 6455 | 5 | PSI_statement_locker *parent_locker = thd->m_statement_psi; | |
| 6456 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | DBUG_TRACE; |
| 6457 | |||
| 6458 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | assert(thd->slave_thread); |
| 6459 | |||
| 6460 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | Parser_state parser_state; |
| 6461 |
4/8✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
|
5 | if (parser_state.init(thd, thd->query().str, thd->query().length) == 0) { |
| 6462 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | lex_start(thd); |
| 6463 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | mysql_reset_thd_for_next_command(thd); |
| 6464 | |||
| 6465 | 5 | thd->m_digest = nullptr; | |
| 6466 | 5 | thd->m_statement_psi = nullptr; | |
| 6467 |
2/4✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
5 | if (parse_sql(thd, &parser_state, nullptr) == 0) { |
| 6468 |
3/4✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
|
5 | if (all_tables_not_ok(thd, lex->query_block->table_list.first)) |
| 6469 | 2 | ignorable = true; | |
| 6470 |
3/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
|
3 | else if (!check_database_filters(thd, thd->db().str, lex->sql_command)) |
| 6471 | 1 | ignorable = true; | |
| 6472 | } | ||
| 6473 | 5 | thd->m_digest = parent_digest; | |
| 6474 | 5 | thd->m_statement_psi = parent_locker; | |
| 6475 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | thd->end_statement(); |
| 6476 | } | ||
| 6477 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | thd->cleanup_after_query(); |
| 6478 | 5 | return ignorable; | |
| 6479 | 5 | } | |
| 6480 | |||
| 6481 | /** | ||
| 6482 | Store field definition for create. | ||
| 6483 | |||
| 6484 | @param thd The thread handler. | ||
| 6485 | @param field_name The field name. | ||
| 6486 | @param type The type of the field. | ||
| 6487 | @param length The length of the field or NULL. | ||
| 6488 | @param decimals The length of a decimal part or NULL. | ||
| 6489 | @param type_modifier Type modifiers & constraint flags of the | ||
| 6490 | field. | ||
| 6491 | @param default_value The default value or NULL. | ||
| 6492 | @param on_update_value The ON UPDATE expression or NULL. | ||
| 6493 | @param comment The comment. | ||
| 6494 | @param change The old column name (if renaming) or NULL. | ||
| 6495 | @param interval_list The list of ENUM/SET values or NULL. | ||
| 6496 | @param cs The character set of the field. | ||
| 6497 | @param has_explicit_collation Column has an explicit COLLATE attribute. | ||
| 6498 | @param uint_geom_type The GIS type of the field. | ||
| 6499 | @param gcol_info The generated column data or NULL. | ||
| 6500 | @param default_val_expr The expression for generating default values, | ||
| 6501 | if there is one, or nullptr. | ||
| 6502 | @param opt_after The name of the field to add after or | ||
| 6503 | the @see first_keyword pointer to insert | ||
| 6504 | first. | ||
| 6505 | @param srid The SRID for this column (only relevant if | ||
| 6506 | this is a geometry column). | ||
| 6507 | @param col_check_const_spec_list List of column check constraints. | ||
| 6508 | @param hidden Column hidden type. | ||
| 6509 | @param is_array Whether it's a typed array field | ||
| 6510 | |||
| 6511 | @return | ||
| 6512 | Return 0 if ok | ||
| 6513 | */ | ||
| 6514 | 4694037 | bool Alter_info::add_field( | |
| 6515 | THD *thd, const LEX_STRING *field_name, enum_field_types type, | ||
| 6516 | const char *length, const char *decimals, uint type_modifier, | ||
| 6517 | Item *default_value, Item *on_update_value, LEX_CSTRING *comment, | ||
| 6518 | const char *change, List<String> *interval_list, const CHARSET_INFO *cs, | ||
| 6519 | bool has_explicit_collation, uint uint_geom_type, | ||
| 6520 | const LEX_CSTRING *zip_dict, Value_generator *gcol_info, | ||
| 6521 | Value_generator *default_val_expr, const char *opt_after, | ||
| 6522 | std::optional<gis::srid_t> srid, | ||
| 6523 | Sql_check_constraint_spec_list *col_check_const_spec_list, | ||
| 6524 | dd::Column::enum_hidden_type hidden, bool is_array) { | ||
| 6525 |
2/2✓ Branch 0 taken 52124 times.
✓ Branch 1 taken 4641913 times.
|
4694037 | uint8 datetime_precision = decimals ? atoi(decimals) : 0; |
| 6526 |
1/2✓ Branch 0 taken 4694038 times.
✗ Branch 1 not taken.
|
4694037 | DBUG_TRACE; |
| 6527 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 4694038 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
4694038 | assert(!is_array || hidden == dd::Column::enum_hidden_type::HT_HIDDEN_SQL); |
| 6528 | |||
| 6529 | 4694038 | LEX_CSTRING field_name_cstr = {field_name->str, field_name->length}; | |
| 6530 | |||
| 6531 |
3/4✓ Branch 0 taken 4694037 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 4694027 times.
|
4694038 | if (check_string_char_length(field_name_cstr, "", NAME_CHAR_LEN, |
| 6532 | system_charset_info, true)) { | ||
| 6533 | 10 | my_error(ER_TOO_LONG_IDENT, MYF(0), | |
| 6534 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | field_name->str); /* purecov: inspected */ |
| 6535 | 10 | return true; /* purecov: inspected */ | |
| 6536 | } | ||
| 6537 |
2/2✓ Branch 0 taken 57946 times.
✓ Branch 1 taken 4636081 times.
|
4694027 | if (type_modifier & PRI_KEY_FLAG) { |
| 6538 | 57946 | List<Key_part_spec> key_parts; | |
| 6539 | auto key_part_spec = | ||
| 6540 |
1/2✓ Branch 0 taken 57946 times.
✗ Branch 1 not taken.
|
57946 | new (thd->mem_root) Key_part_spec(field_name_cstr, 0, ORDER_ASC); |
| 6541 |
4/8✓ Branch 0 taken 57946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57946 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 57946 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 57946 times.
|
57946 | if (key_part_spec == nullptr || key_parts.push_back(key_part_spec)) |
| 6542 | ✗ | return true; | |
| 6543 | Key_spec *key = new (thd->mem_root) | ||
| 6544 | Key_spec(thd->mem_root, KEYTYPE_PRIMARY, NULL_CSTR, | ||
| 6545 |
2/4✓ Branch 0 taken 57946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57946 times.
✗ Branch 3 not taken.
|
57946 | &default_key_create_info, false, true, key_parts); |
| 6546 |
4/8✓ Branch 0 taken 57946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57946 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 57946 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 57946 times.
|
57946 | if (key == nullptr || key_list.push_back(key)) return true; |
| 6547 | } | ||
| 6548 |
2/2✓ Branch 0 taken 2673 times.
✓ Branch 1 taken 4691354 times.
|
4694027 | if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG | CLUSTERING_FLAG)) { |
| 6549 | enum keytype key_type; | ||
| 6550 |
2/2✓ Branch 0 taken 2671 times.
✓ Branch 1 taken 2 times.
|
2673 | if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) |
| 6551 | 2671 | key_type = KEYTYPE_UNIQUE; | |
| 6552 | else | ||
| 6553 | 2 | key_type = KEYTYPE_MULTIPLE; | |
| 6554 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2667 times.
|
2673 | if (type_modifier & CLUSTERING_FLAG) |
| 6555 | 6 | key_type = static_cast<enum keytype>(key_type | KEYTYPE_CLUSTERING); | |
| 6556 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2673 times.
|
2673 | assert(key_type != KEYTYPE_MULTIPLE); |
| 6557 | 2673 | List<Key_part_spec> key_parts; | |
| 6558 | auto key_part_spec = | ||
| 6559 |
1/2✓ Branch 0 taken 2673 times.
✗ Branch 1 not taken.
|
2673 | new (thd->mem_root) Key_part_spec(field_name_cstr, 0, ORDER_ASC); |
| 6560 |
4/8✓ Branch 0 taken 2673 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2673 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2673 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2673 times.
|
2673 | if (key_part_spec == nullptr || key_parts.push_back(key_part_spec)) |
| 6561 | ✗ | return true; | |
| 6562 | Key_spec *key = new (thd->mem_root) | ||
| 6563 | Key_spec(thd->mem_root, key_type, NULL_CSTR, &default_key_create_info, | ||
| 6564 |
2/4✓ Branch 0 taken 2673 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2673 times.
✗ Branch 3 not taken.
|
2673 | false, true, key_parts); |
| 6565 |
4/8✓ Branch 0 taken 2673 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2673 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2673 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2673 times.
|
2673 | if (key == nullptr || key_list.push_back(key)) return true; |
| 6566 | } | ||
| 6567 | |||
| 6568 |
2/2✓ Branch 0 taken 306489 times.
✓ Branch 1 taken 4387538 times.
|
4694027 | if (default_value) { |
| 6569 | /* | ||
| 6570 | Default value should be literal => basic constants => | ||
| 6571 | no need fix_fields() | ||
| 6572 | |||
| 6573 | We allow only CURRENT_TIMESTAMP as function default for the TIMESTAMP or | ||
| 6574 | DATETIME types. In addition, TRUE and FALSE are allowed for bool types. | ||
| 6575 | */ | ||
| 6576 |
3/4✓ Branch 0 taken 306489 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45517 times.
✓ Branch 3 taken 260972 times.
|
306489 | if (default_value->type() == Item::FUNC_ITEM) { |
| 6577 | 45517 | Item_func *func = down_cast<Item_func *>(default_value); | |
| 6578 |
3/4✓ Branch 0 taken 45517 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1334 times.
✓ Branch 3 taken 44183 times.
|
45517 | if (func->basic_const_item()) { |
| 6579 |
3/4✓ Branch 0 taken 1334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1329 times.
|
1334 | if (func->result_type() != INT_RESULT) { |
| 6580 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str); |
| 6581 | 5 | return true; | |
| 6582 | } | ||
| 6583 |
5/8✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1320 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 1320 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1320 times.
|
1329 | assert(dynamic_cast<Item_func_true *>(func) || |
| 6584 | dynamic_cast<Item_func_false *>(func)); | ||
| 6585 |
3/6✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1329 times.
✗ Branch 5 not taken.
|
1329 | default_value = new Item_int(func->val_int()); |
| 6586 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1329 times.
|
1329 | if (default_value == nullptr) return true; |
| 6587 |
1/2✓ Branch 0 taken 44183 times.
✗ Branch 1 not taken.
|
44183 | } else if (func->functype() != Item_func::NOW_FUNC || |
| 6588 |
5/6✓ Branch 0 taken 44183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44161 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 60 times.
✓ Branch 5 taken 44123 times.
|
88344 | !real_type_with_now_as_default(type) || |
| 6589 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 44123 times.
|
44161 | default_value->decimals != datetime_precision) { |
| 6590 |
1/2✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
|
60 | my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str); |
| 6591 | 60 | return true; | |
| 6592 | } | ||
| 6593 |
3/4✓ Branch 0 taken 260972 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 142912 times.
✓ Branch 3 taken 118060 times.
|
260972 | } else if (default_value->type() == Item::NULL_ITEM) { |
| 6594 | 142912 | default_value = nullptr; | |
| 6595 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 142910 times.
|
142912 | if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == |
| 6596 | NOT_NULL_FLAG) { | ||
| 6597 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str); |
| 6598 | 2 | return true; | |
| 6599 | } | ||
| 6600 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 118059 times.
|
118060 | } else if (type_modifier & AUTO_INCREMENT_FLAG) { |
| 6601 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str); |
| 6602 | 1 | return true; | |
| 6603 | } | ||
| 6604 | } | ||
| 6605 | |||
| 6606 | // 1) Reject combinations of DEFAULT <value> and DEFAULT (<expression>). | ||
| 6607 | // 2) Reject combinations of DEFAULT (<expression>) and AUTO_INCREMENT. | ||
| 6608 | // (Combinations of DEFAULT <value> and AUTO_INCREMENT are rejected above.) | ||
| 6609 |
6/6✓ Branch 0 taken 309 times.
✓ Branch 1 taken 4693650 times.
✓ Branch 2 taken 306 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 306 times.
✓ Branch 5 taken 4693650 times.
|
4693959 | if ((default_val_expr && default_value) || |
| 6610 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 303 times.
|
306 | (default_val_expr && (type_modifier & AUTO_INCREMENT_FLAG))) { |
| 6611 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
6 | my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str); |
| 6612 | 5 | return true; | |
| 6613 | } | ||
| 6614 | |||
| 6615 |
6/6✓ Branch 0 taken 33832 times.
✓ Branch 1 taken 4660121 times.
✓ Branch 2 taken 33810 times.
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 4693919 times.
|
4727763 | if (on_update_value && (!real_type_with_now_on_update(type) || |
| 6616 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 33798 times.
|
33810 | on_update_value->decimals != datetime_precision)) { |
| 6617 |
1/2✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
|
34 | my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str); |
| 6618 | 34 | return true; | |
| 6619 | } | ||
| 6620 | |||
| 6621 | // If the SRID is specified on a non-geometric column, return an error | ||
| 6622 |
6/6✓ Branch 0 taken 4692474 times.
✓ Branch 1 taken 1445 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4692470 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 4693915 times.
|
4693919 | if (type != MYSQL_TYPE_GEOMETRY && srid.has_value()) { |
| 6623 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | my_error(ER_WRONG_USAGE, MYF(0), "SRID", "non-geometry column"); |
| 6624 | 5 | return true; | |
| 6625 | } | ||
| 6626 | |||
| 6627 |
1/2✓ Branch 0 taken 4693915 times.
✗ Branch 1 not taken.
|
9387831 | Create_field *new_field = new (thd->mem_root) Create_field(); |
| 6628 |
3/4✓ Branch 0 taken 4693916 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 159 times.
✓ Branch 3 taken 4693757 times.
|
9387832 | if ((new_field == nullptr) || |
| 6629 |
3/4✓ Branch 0 taken 4693916 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 159 times.
✓ Branch 3 taken 4693757 times.
|
4693916 | new_field->init(thd, field_name->str, type, length, decimals, |
| 6630 | type_modifier, default_value, on_update_value, comment, | ||
| 6631 | change, interval_list, cs, has_explicit_collation, | ||
| 6632 | uint_geom_type, zip_dict, gcol_info, default_val_expr, | ||
| 6633 | srid, hidden, is_array)) | ||
| 6634 | 159 | return true; | |
| 6635 | |||
| 6636 |
2/2✓ Branch 0 taken 105 times.
✓ Branch 1 taken 4693757 times.
|
4693862 | for (const auto &a : cf_appliers) { |
| 6637 |
2/4✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 105 times.
|
105 | if (a(new_field, this)) return true; |
| 6638 | } | ||
| 6639 | |||
| 6640 |
1/2✓ Branch 0 taken 4693757 times.
✗ Branch 1 not taken.
|
4693757 | create_list.push_back(new_field); |
| 6641 |
2/2✓ Branch 0 taken 15144 times.
✓ Branch 1 taken 4678613 times.
|
4693757 | if (opt_after != nullptr) { |
| 6642 | 15144 | flags |= Alter_info::ALTER_COLUMN_ORDER; | |
| 6643 | 15144 | new_field->after = opt_after; | |
| 6644 | } | ||
| 6645 | |||
| 6646 |
1/2✓ Branch 0 taken 4693757 times.
✗ Branch 1 not taken.
|
4693757 | if (col_check_const_spec_list) { |
| 6647 | /* | ||
| 6648 | Set column name, required for column check constraint validation in | ||
| 6649 | Sql_check_constraint_spec::pre_validate(). | ||
| 6650 | */ | ||
| 6651 |
3/4✓ Branch 0 taken 4693756 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 207 times.
✓ Branch 3 taken 4693756 times.
|
4693964 | for (auto &cc_spec : *col_check_const_spec_list) { |
| 6652 | 207 | cc_spec->column_name = *field_name; | |
| 6653 | } | ||
| 6654 | /* | ||
| 6655 | Move column check constraint specifications to table check constraints | ||
| 6656 | specifications list. | ||
| 6657 | */ | ||
| 6658 |
2/4✓ Branch 0 taken 4693757 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4693757 times.
✗ Branch 3 not taken.
|
4693756 | std::move(col_check_const_spec_list->begin(), |
| 6659 | col_check_const_spec_list->end(), | ||
| 6660 |
1/2✓ Branch 0 taken 4693756 times.
✗ Branch 1 not taken.
|
4693756 | std::back_inserter(check_constraint_spec_list)); |
| 6661 | } | ||
| 6662 | |||
| 6663 | 4693757 | return false; | |
| 6664 | 4694038 | } | |
| 6665 | |||
| 6666 | /** | ||
| 6667 | save order by and tables in own lists. | ||
| 6668 | */ | ||
| 6669 | |||
| 6670 | ✗ | void add_to_list(SQL_I_List<ORDER> &list, ORDER *order) { | |
| 6671 | ✗ | DBUG_TRACE; | |
| 6672 | ✗ | order->used_alias = false; | |
| 6673 | ✗ | order->used = 0; | |
| 6674 | ✗ | list.link_in_list(order, &order->next); | |
| 6675 | } | ||
| 6676 | |||
| 6677 | /** | ||
| 6678 | Produces a PT_subquery object from a subquery's text. | ||
| 6679 | @param thd Thread handler | ||
| 6680 | @param text Subquery's text | ||
| 6681 | @param text_length Length of 'text' | ||
| 6682 | @param text_offset Offset in bytes of 'text' in the original statement | ||
| 6683 | @param[out] node Produced PT_subquery object | ||
| 6684 | |||
| 6685 | @returns true if error | ||
| 6686 | */ | ||
| 6687 | 7161 | static bool reparse_common_table_expr(THD *thd, const char *text, | |
| 6688 | size_t text_length, uint text_offset, | ||
| 6689 | PT_subquery **node) { | ||
| 6690 |
1/2✓ Branch 0 taken 7161 times.
✗ Branch 1 not taken.
|
7161 | Common_table_expr_parser_state parser_state; |
| 6691 |
1/2✓ Branch 0 taken 7161 times.
✗ Branch 1 not taken.
|
7161 | parser_state.init(thd, text, text_length); |
| 6692 | |||
| 6693 | 7161 | Parser_state *old = thd->m_parser_state; | |
| 6694 | 7161 | thd->m_parser_state = &parser_state; | |
| 6695 | |||
| 6696 | /* | ||
| 6697 | Re-parsing a CTE creates Item_param-s and Item_sp_local-s which are | ||
| 6698 | special, as they do not exist in the original query: thus they should not | ||
| 6699 | exist from the points of view of logging. | ||
| 6700 | This is achieved like this: | ||
| 6701 | - for SP local vars: their pos_in_query is set to 0 | ||
| 6702 | - for PS parameters: they are not added to LEX::param_list and thus not to | ||
| 6703 | Prepared_statement::param_array. | ||
| 6704 | They still need a value, which they get like this: | ||
| 6705 | - for SP local vars: through the ordinary look-up of SP local | ||
| 6706 | variables' values by name of the variable. | ||
| 6707 | - for PS parameters: first the first-parsed, 'non-special' Item-params, | ||
| 6708 | which are in param_array, get their value bound from user-supplied data, | ||
| 6709 | then they propagate their value to their 'special' clones (@see | ||
| 6710 | Item_param::m_clones). | ||
| 6711 | */ | ||
| 6712 | 7161 | parser_state.m_lip.stmt_prepare_mode = old->m_lip.stmt_prepare_mode; | |
| 6713 | 7161 | parser_state.m_lip.multi_statements = false; // A safety measure. | |
| 6714 | 7161 | parser_state.m_lip.m_digest = nullptr; | |
| 6715 | |||
| 6716 | // This is saved and restored by caller: | ||
| 6717 | 7161 | thd->lex->reparse_common_table_expr_at = text_offset; | |
| 6718 | |||
| 6719 | /* | ||
| 6720 | As this function is called during parsing only, it can and should use the | ||
| 6721 | current Query_arena, character_set_client, etc. | ||
| 6722 | It intentionally uses THD::sql_parser() directly without the parse_sql() | ||
| 6723 | wrapper: because it's building a node of the statement currently being | ||
| 6724 | parsed at the upper call site. | ||
| 6725 | */ | ||
| 6726 |
1/2✓ Branch 0 taken 7161 times.
✗ Branch 1 not taken.
|
7161 | bool mysql_parse_status = thd->sql_parser(); |
| 6727 | 7161 | thd->m_parser_state = old; | |
| 6728 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7161 times.
|
7161 | if (mysql_parse_status) return true; /* purecov: inspected */ |
| 6729 | |||
| 6730 | 7161 | *node = parser_state.result; | |
| 6731 | 7161 | return false; | |
| 6732 | 7161 | } | |
| 6733 | |||
| 6734 | 7855 | bool PT_common_table_expr::make_subquery_node(THD *thd, PT_subquery **node) { | |
| 6735 |
2/2✓ Branch 0 taken 481 times.
✓ Branch 1 taken 7374 times.
|
7855 | if (m_postparse.references.size() >= 2) { |
| 6736 | // m_subq_node was already attached elsewhere, make new node: | ||
| 6737 | 481 | return reparse_common_table_expr(thd, m_subq_text.str, m_subq_text.length, | |
| 6738 | 481 | m_subq_text_offset, node); | |
| 6739 | } | ||
| 6740 | 7374 | *node = m_subq_node; | |
| 6741 | 7374 | return false; | |
| 6742 | } | ||
| 6743 | |||
| 6744 | /** | ||
| 6745 | Tries to match an identifier to the CTEs in scope; if matched, it | ||
| 6746 | modifies *table_name, *tl', and the matched with-list-element. | ||
| 6747 | |||
| 6748 | @param thd Thread handler | ||
| 6749 | @param[out] table_name Identifier | ||
| 6750 | @param[in,out] tl TABLE_LIST for the identifier | ||
| 6751 | @param pc Current parsing context, if available | ||
| 6752 | @param[out] found Is set to true if found. | ||
| 6753 | |||
| 6754 | @returns true if error (OOM). | ||
| 6755 | */ | ||
| 6756 | 4345059 | bool Query_block::find_common_table_expr(THD *thd, Table_ident *table_name, | |
| 6757 | TABLE_LIST *tl, Parse_context *pc, | ||
| 6758 | bool *found) { | ||
| 6759 | 4345059 | *found = false; | |
| 6760 |
2/2✓ Branch 0 taken 3542651 times.
✓ Branch 1 taken 802408 times.
|
4345059 | if (!pc) return false; |
| 6761 | |||
| 6762 | PT_with_clause *wc; | ||
| 6763 | 802408 | PT_common_table_expr *cte = nullptr; | |
| 6764 | 802408 | Query_block *select = this; | |
| 6765 | Query_expression *unit; | ||
| 6766 | do { | ||
| 6767 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 988971 times.
|
988971 | assert(select->first_execution); |
| 6768 | 988971 | unit = select->master_query_expression(); | |
| 6769 |
2/2✓ Branch 0 taken 972917 times.
✓ Branch 1 taken 16052 times.
|
988969 | if (!(wc = unit->m_with_clause)) continue; |
| 6770 |
3/4✓ Branch 0 taken 16054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 16044 times.
|
16052 | if (wc->lookup(tl, &cte)) return true; |
| 6771 | /* | ||
| 6772 | If no match in the WITH clause of 'select', maybe this is a subquery, so | ||
| 6773 | look up in the outer query's WITH clause: | ||
| 6774 | */ | ||
| 6775 |
6/6✓ Branch 0 taken 974433 times.
✓ Branch 1 taken 14528 times.
✓ Branch 2 taken 186520 times.
✓ Branch 3 taken 787911 times.
✓ Branch 4 taken 186563 times.
✓ Branch 5 taken 802396 times.
|
988961 | } while (cte == nullptr && (select = unit->outer_query_block())); |
| 6776 | |||
| 6777 |
2/2✓ Branch 0 taken 787912 times.
✓ Branch 1 taken 14484 times.
|
802396 | if (cte == nullptr) return false; |
| 6778 | 14484 | *found = true; | |
| 6779 | |||
| 6780 | 14484 | const auto save_reparse_cte = thd->lex->reparse_common_table_expr_at; | |
| 6781 | PT_subquery *node; | ||
| 6782 |
2/2✓ Branch 0 taken 6680 times.
✓ Branch 1 taken 7855 times.
|
14484 | if (tl->is_recursive_reference()) { |
| 6783 | /* | ||
| 6784 | To pass the first steps of resolution, a recursive reference is here | ||
| 6785 | made to be a dummy derived table; after the temporary table is created | ||
| 6786 | based on the non-recursive members' types, the recursive reference is | ||
| 6787 | made to be a reference to the tmp table. | ||
| 6788 | */ | ||
| 6789 | 6680 | LEX_CSTRING dummy_subq = {STRING_WITH_LEN("(select 0)")}; | |
| 6790 |
2/4✓ Branch 0 taken 6680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6680 times.
|
6680 | if (reparse_common_table_expr(thd, dummy_subq.str, dummy_subq.length, 0, |
| 6791 | &node)) | ||
| 6792 | ✗ | return true; /* purecov: inspected */ | |
| 6793 |
2/4✓ Branch 0 taken 7855 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7855 times.
|
7855 | } else if (cte->make_subquery_node(thd, &node)) |
| 6794 | ✗ | return true; /* purecov: inspected */ | |
| 6795 | // We imitate derived tables as much as possible. | ||
| 6796 |
2/4✓ Branch 0 taken 14535 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14535 times.
✗ Branch 3 not taken.
|
14535 | assert(parsing_place == CTX_NONE && linkage != GLOBAL_OPTIONS_TYPE); |
| 6797 | 14535 | parsing_place = CTX_DERIVED; | |
| 6798 | 14535 | node->m_is_derived_table = true; | |
| 6799 | 14535 | auto wc_save = wc->enter_parsing_definition(tl); | |
| 6800 | |||
| 6801 | /* | ||
| 6802 | The proper outer context for the CTE, is not the query block where the CTE | ||
| 6803 | reference is; neither is it the outer query block of this. It is the query | ||
| 6804 | block which immediately contains the query expression where the CTE | ||
| 6805 | definition is. Indeed, per the standard, evaluation of the CTE happens | ||
| 6806 | as first step of evaluation of the said query expression; so the CTE may | ||
| 6807 | not contain references into the said query expression. | ||
| 6808 | */ | ||
| 6809 |
3/4✓ Branch 0 taken 213 times.
✓ Branch 1 taken 14322 times.
✓ Branch 2 taken 14535 times.
✗ Branch 3 not taken.
|
14748 | thd->lex->push_context(unit->outer_query_block() |
| 6810 | 213 | ? &unit->outer_query_block()->context | |
| 6811 | : nullptr); | ||
| 6812 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14535 times.
|
14535 | assert(thd->lex->will_contextualize); |
| 6813 |
3/4✓ Branch 0 taken 14535 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 14525 times.
|
14535 | if (node->contextualize(pc)) return true; |
| 6814 | |||
| 6815 |
1/2✓ Branch 0 taken 14525 times.
✗ Branch 1 not taken.
|
14525 | thd->lex->pop_context(); |
| 6816 | |||
| 6817 | 14525 | wc->leave_parsing_definition(wc_save); | |
| 6818 | 14525 | parsing_place = CTX_NONE; | |
| 6819 | /* | ||
| 6820 | Prepared statement's parameters and SP local variables are spotted as | ||
| 6821 | 'made during re-parsing' by node->contextualize(), which is why we | ||
| 6822 | ran that call _before_ restoring lex->reparse_common_table_expr_at. | ||
| 6823 | */ | ||
| 6824 | 14525 | thd->lex->reparse_common_table_expr_at = save_reparse_cte; | |
| 6825 | 14525 | tl->is_alias = true; | |
| 6826 | Query_expression *node_query_expression = | ||
| 6827 | 14525 | node->value()->master_query_expression(); | |
| 6828 | 14525 | *table_name = Table_ident(node_query_expression); | |
| 6829 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14525 times.
|
14525 | assert(table_name->is_derived_table()); |
| 6830 | 14525 | tl->db = table_name->db.str; | |
| 6831 | 14525 | tl->db_length = table_name->db.length; | |
| 6832 | 14525 | return false; | |
| 6833 | } | ||
| 6834 | |||
| 6835 | 16054 | bool PT_with_clause::lookup(TABLE_LIST *tl, PT_common_table_expr **found) { | |
| 6836 | 16054 | *found = nullptr; | |
| 6837 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16054 times.
|
16054 | assert(tl->query_block != nullptr); |
| 6838 | /* | ||
| 6839 | If right_bound!=NULL, it means we are currently parsing the | ||
| 6840 | definition of CTE 'right_bound' and this definition contains | ||
| 6841 | 'tl'. | ||
| 6842 | */ | ||
| 6843 | const Common_table_expr *right_bound = | ||
| 6844 |
2/2✓ Branch 0 taken 8189 times.
✓ Branch 1 taken 7865 times.
|
16054 | m_most_inner_in_parsing ? m_most_inner_in_parsing->common_table_expr() |
| 6845 | 16054 | : nullptr; | |
| 6846 | 16054 | bool in_self = false; | |
| 6847 |
2/2✓ Branch 0 taken 16526 times.
✓ Branch 1 taken 141 times.
|
16667 | for (auto el : m_list->elements()) { |
| 6848 | // Search for a CTE named like 'tl', in this list, from left to right. | ||
| 6849 |
2/2✓ Branch 0 taken 8058 times.
✓ Branch 1 taken 8468 times.
|
16526 | if (el->is(right_bound)) { |
| 6850 | /* | ||
| 6851 | We meet right_bound. | ||
| 6852 | If not RECURSIVE: | ||
| 6853 | we must stop the search in this WITH clause; | ||
| 6854 | indeed right_bound must not reference itself or any CTE defined after it | ||
| 6855 | in the WITH list (forward references are forbidden, preventing any | ||
| 6856 | cycle). | ||
| 6857 | If RECURSIVE: | ||
| 6858 | If right_bound matches 'tl', it is a recursive reference. | ||
| 6859 | */ | ||
| 6860 |
2/2✓ Branch 0 taken 1083 times.
✓ Branch 1 taken 6975 times.
|
22878 | if (!m_recursive) break; // Prevent forward reference. |
| 6861 | 6975 | in_self = true; // Accept a recursive reference. | |
| 6862 | } | ||
| 6863 | bool match; | ||
| 6864 |
3/4✓ Branch 0 taken 15443 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 15441 times.
|
15451 | if (el->match_table_ref(tl, in_self, &match)) return true; |
| 6865 |
2/2✓ Branch 0 taken 898 times.
✓ Branch 1 taken 14543 times.
|
15441 | if (!match) { |
| 6866 |
2/2✓ Branch 0 taken 285 times.
✓ Branch 1 taken 613 times.
|
898 | if (in_self) break; // Prevent forward reference. |
| 6867 | 613 | continue; | |
| 6868 | } | ||
| 6869 |
4/4✓ Branch 0 taken 6688 times.
✓ Branch 1 taken 7855 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 14535 times.
|
21231 | if (in_self && tl->query_block->outer_query_block() != |
| 6870 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6680 times.
|
6688 | m_most_inner_in_parsing->query_block) { |
| 6871 | /* | ||
| 6872 | SQL2011 says a recursive CTE cannot contain a subquery | ||
| 6873 | referencing the CTE, except if this subquery is a derived table | ||
| 6874 | like: | ||
| 6875 | WITH RECURSIVE qn AS (non-rec-SELECT UNION ALL | ||
| 6876 | SELECT * FROM (SELECT * FROM qn) AS dt) | ||
| 6877 | However, we don't allow this, as: | ||
| 6878 | - it simplifies detection and substitution correct recursive | ||
| 6879 | references (they're all on "level 0" of the UNION) | ||
| 6880 | - it's not limiting the user so much (in most cases, he can just | ||
| 6881 | merge his DT up manually, as the DT cannot contain aggregation). | ||
| 6882 | - Oracle bans it: | ||
| 6883 | with qn (a) as ( | ||
| 6884 | select 123 from dual | ||
| 6885 | union all | ||
| 6886 | select 1+a from (select * from qn) where a<130) select * from qn | ||
| 6887 | ORA-32042: recursive WITH clause must reference itself directly in one | ||
| 6888 | of the UNION ALL branches. | ||
| 6889 | |||
| 6890 | The above if() works because, when we parse such example query, we | ||
| 6891 | first resolve the 'qn' reference in the top query, making it a derived | ||
| 6892 | table: | ||
| 6893 | |||
| 6894 | select * from ( | ||
| 6895 | select 123 from dual | ||
| 6896 | union all | ||
| 6897 | select 1+a from (select * from qn) where a<130) qn(a); | ||
| 6898 | ^most_inner_in_parsing | ||
| 6899 | Then we contextualize that derived table (containing the union); | ||
| 6900 | when we contextualize the recursive query block of the union, the | ||
| 6901 | inner 'qn' is recognized as a recursive reference, and its | ||
| 6902 | query_block->outer_query_block() is _not_ the query_block of | ||
| 6903 | most_inner_in_parsing, which indicates that the inner 'qn' is placed | ||
| 6904 | too deep. | ||
| 6905 | */ | ||
| 6906 | 8 | my_error(ER_CTE_RECURSIVE_REQUIRES_SINGLE_REFERENCE, MYF(0), | |
| 6907 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | el->name().str); |
| 6908 | 8 | return true; | |
| 6909 | } | ||
| 6910 | 14535 | *found = el; | |
| 6911 | 14535 | break; | |
| 6912 | } | ||
| 6913 | 16044 | return false; | |
| 6914 | } | ||
| 6915 | |||
| 6916 | 15443 | bool PT_common_table_expr::match_table_ref(TABLE_LIST *tl, bool in_self, | |
| 6917 | bool *found) { | ||
| 6918 | 15443 | *found = false; | |
| 6919 |
2/2✓ Branch 0 taken 14862 times.
✓ Branch 1 taken 581 times.
|
15443 | if (tl->table_name_length == m_name.length && |
| 6920 | /* | ||
| 6921 | memcmp() is fine even if lower_case_table_names==1, as CTE names | ||
| 6922 | have been lowercased in the ctor. | ||
| 6923 | */ | ||
| 6924 |
2/2✓ Branch 0 taken 14545 times.
✓ Branch 1 taken 317 times.
|
14862 | !memcmp(tl->table_name, m_name.str, m_name.length)) { |
| 6925 | 14545 | *found = true; | |
| 6926 | // 'tl' is a reference to CTE 'el'. | ||
| 6927 |
2/2✓ Branch 0 taken 6690 times.
✓ Branch 1 taken 7855 times.
|
14545 | if (in_self) { |
| 6928 | 6690 | m_postparse.recursive = true; | |
| 6929 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6688 times.
|
6690 | if (tl->set_recursive_reference()) { |
| 6930 | 2 | my_error(ER_CTE_RECURSIVE_REQUIRES_SINGLE_REFERENCE, MYF(0), | |
| 6931 | 2 | name().str); | |
| 6932 | 2 | return true; | |
| 6933 | } | ||
| 6934 | } else { | ||
| 6935 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7855 times.
|
7855 | if (m_postparse.references.push_back(tl)) |
| 6936 | ✗ | return true; /* purecov: inspected */ | |
| 6937 |
2/2✓ Branch 0 taken 6791 times.
✓ Branch 1 taken 1064 times.
|
7855 | if (m_column_names.size()) tl->set_derived_column_names(&m_column_names); |
| 6938 | } | ||
| 6939 | 14543 | tl->set_common_table_expr(&m_postparse); | |
| 6940 | } | ||
| 6941 | 15441 | return false; | |
| 6942 | } | ||
| 6943 | |||
| 6944 | /** | ||
| 6945 | Add a table to list of used tables. | ||
| 6946 | |||
| 6947 | @param thd Current session. | ||
| 6948 | @param table_name Table to add | ||
| 6949 | @param alias alias for table (or null if no alias) | ||
| 6950 | @param table_options A set of the following bits: | ||
| 6951 | - TL_OPTION_UPDATING : Table will be updated | ||
| 6952 | - TL_OPTION_FORCE_INDEX : Force usage of index | ||
| 6953 | - TL_OPTION_ALIAS : an alias in multi table DELETE | ||
| 6954 | @param lock_type How table should be locked | ||
| 6955 | @param mdl_type Type of metadata lock to acquire on the table. | ||
| 6956 | @param index_hints_arg a list of index hints(FORCE/USE/IGNORE INDEX). | ||
| 6957 | @param partition_names List to carry partition names from PARTITION (...) | ||
| 6958 | clause in statement | ||
| 6959 | @param option Used by cache index | ||
| 6960 | @param pc Current parsing context, if available. | ||
| 6961 | |||
| 6962 | @return Pointer to TABLE_LIST element added to the total table list | ||
| 6963 | @retval | ||
| 6964 | 0 Error | ||
| 6965 | */ | ||
| 6966 | |||
| 6967 | 11757058 | TABLE_LIST *Query_block::add_table_to_list( | |
| 6968 | THD *thd, Table_ident *table_name, const char *alias, ulong table_options, | ||
| 6969 | thr_lock_type lock_type, enum_mdl_type mdl_type, | ||
| 6970 | List<Index_hint> *index_hints_arg, List<String> *partition_names, | ||
| 6971 | LEX_STRING *option, Parse_context *pc) { | ||
| 6972 | 11757058 | TABLE_LIST *previous_table_ref = | |
| 6973 | nullptr; /* The table preceding the current one. */ | ||
| 6974 | 11757058 | LEX *lex = thd->lex; | |
| 6975 |
1/2✓ Branch 0 taken 11758455 times.
✗ Branch 1 not taken.
|
11757058 | DBUG_TRACE; |
| 6976 | |||
| 6977 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11758455 times.
|
11758455 | assert(table_name != nullptr); |
| 6978 | // A derived table has no table name, only an alias. | ||
| 6979 |
6/6✓ Branch 0 taken 11756410 times.
✓ Branch 1 taken 2045 times.
✓ Branch 2 taken 11527131 times.
✓ Branch 3 taken 229233 times.
✓ Branch 4 taken 11527316 times.
✓ Branch 5 taken 231093 times.
|
11758455 | if (!(table_options & TL_OPTION_ALIAS) && !table_name->is_derived_table()) { |
| 6980 | Ident_name_check ident_check_status = | ||
| 6981 |
1/2✓ Branch 0 taken 11527372 times.
✗ Branch 1 not taken.
|
11527316 | check_table_name(table_name->table.str, table_name->table.length); |
| 6982 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 11527354 times.
|
11527372 | if (ident_check_status == Ident_name_check::WRONG) { |
| 6983 |
1/2✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
|
18 | my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name->table.str); |
| 6984 | 18 | return nullptr; | |
| 6985 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 11527345 times.
|
11527354 | } else if (ident_check_status == Ident_name_check::TOO_LONG) { |
| 6986 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | my_error(ER_TOO_LONG_IDENT, MYF(0), table_name->table.str); |
| 6987 | 9 | return nullptr; | |
| 6988 | } | ||
| 6989 | } | ||
| 6990 | 11758438 | LEX_STRING db = to_lex_string(table_name->db); | |
| 6991 |
2/2✓ Branch 0 taken 11520611 times.
✓ Branch 1 taken 7958 times.
|
23285916 | if (!table_name->is_derived_table() && !table_name->is_table_function() && |
| 6992 |
6/6✓ Branch 0 taken 11528508 times.
✓ Branch 1 taken 229056 times.
✓ Branch 2 taken 7173835 times.
✓ Branch 3 taken 4346776 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 11757649 times.
|
30459998 | table_name->db.str && |
| 6993 |
3/4✓ Branch 0 taken 7173865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 7173859 times.
|
7173835 | (check_and_convert_db_name(&db, false) != Ident_name_check::OK)) |
| 6994 | 6 | return nullptr; | |
| 6995 | |||
| 6996 |
2/2✓ Branch 0 taken 9043360 times.
✓ Branch 1 taken 2714289 times.
|
11757649 | const char *alias_str = alias ? alias : table_name->table.str; |
| 6997 |
2/2✓ Branch 0 taken 9043506 times.
✓ Branch 1 taken 2714143 times.
|
11757649 | if (!alias) /* Alias is case sensitive */ |
| 6998 | { | ||
| 6999 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9043506 times.
|
9043506 | if (table_name->sel) { |
| 7000 | ✗ | my_error(ER_DERIVED_MUST_HAVE_ALIAS, MYF(0)); | |
| 7001 | ✗ | return nullptr; | |
| 7002 | } | ||
| 7003 | 9043425 | if (!(alias_str = | |
| 7004 |
2/4✓ Branch 0 taken 9043425 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9043425 times.
|
9043506 | (char *)thd->memdup(alias_str, table_name->table.length + 1))) |
| 7005 | ✗ | return nullptr; | |
| 7006 | } | ||
| 7007 | |||
| 7008 |
2/4✓ Branch 0 taken 11757948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11758467 times.
✗ Branch 3 not taken.
|
11757568 | TABLE_LIST *ptr = new (thd->mem_root) TABLE_LIST; |
| 7009 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11758467 times.
|
11758467 | if (ptr == nullptr) return nullptr; /* purecov: inspected */ |
| 7010 | |||
| 7011 |
4/4✓ Branch 0 taken 652789 times.
✓ Branch 1 taken 11105678 times.
✓ Branch 2 taken 651646 times.
✓ Branch 3 taken 1143 times.
|
11758467 | if (lower_case_table_names && table_name->table.length) |
| 7012 |
1/2✓ Branch 0 taken 651646 times.
✗ Branch 1 not taken.
|
651646 | table_name->table.length = my_casedn_str( |
| 7013 | files_charset_info, const_cast<char *>(table_name->table.str)); | ||
| 7014 | |||
| 7015 | 11758467 | ptr->query_block = this; | |
| 7016 | 11758467 | ptr->table_name = table_name->table.str; | |
| 7017 | 11758467 | ptr->table_name_length = table_name->table.length; | |
| 7018 | 11758467 | ptr->alias = alias_str; | |
| 7019 | 11758467 | ptr->is_alias = alias != nullptr; | |
| 7020 | 11758467 | ptr->table_function = table_name->table_function; | |
| 7021 |
2/2✓ Branch 0 taken 7967 times.
✓ Branch 1 taken 11750500 times.
|
11758467 | if (table_name->table_function) { |
| 7022 | 7967 | table_func_count++; | |
| 7023 | 7967 | ptr->derived_key_list.clear(); | |
| 7024 | } | ||
| 7025 | |||
| 7026 |
2/2✓ Branch 0 taken 7411080 times.
✓ Branch 1 taken 4346973 times.
|
11758053 | if (table_name->db.str) { |
| 7027 | 7411080 | ptr->is_fqtn = true; | |
| 7028 | 7411080 | ptr->db = table_name->db.str; | |
| 7029 | 7411080 | ptr->db_length = table_name->db.length; | |
| 7030 | } else { | ||
| 7031 | // Check if the unqualified name could refer to a CTE. Don't do this for the | ||
| 7032 | // alias list of a multi-table DELETE statement (TL_OPTION_ALIAS), since | ||
| 7033 | // those are only references into the FROM list, and any CTEs referenced by | ||
| 7034 | // the aliases will be resolved when we later resolve the FROM list. | ||
| 7035 | 4346973 | bool found_cte = false; | |
| 7036 |
2/2✓ Branch 0 taken 4345647 times.
✓ Branch 1 taken 1326 times.
|
4346973 | if ((table_options & TL_OPTION_ALIAS) == 0) { |
| 7037 |
3/4✓ Branch 0 taken 4345115 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 4345095 times.
|
4345647 | if (find_common_table_expr(thd, table_name, ptr, pc, &found_cte)) |
| 7038 | 68 | return nullptr; | |
| 7039 | } | ||
| 7040 |
7/8✓ Branch 0 taken 4332076 times.
✓ Branch 1 taken 14345 times.
✓ Branch 2 taken 4332008 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 4331960 times.
✓ Branch 6 taken 48 times.
✓ Branch 7 taken 4346305 times.
|
4346421 | if (!found_cte && lex->copy_db_to(&ptr->db, &ptr->db_length)) |
| 7041 | 48 | return nullptr; | |
| 7042 | } | ||
| 7043 | |||
| 7044 | 11757385 | ptr->set_tableno(0); | |
| 7045 | 11757365 | ptr->set_lock({lock_type, THR_DEFAULT}); | |
| 7046 | 11757721 | ptr->updating = table_options & TL_OPTION_UPDATING; | |
| 7047 | 11757721 | ptr->ignore_leaves = table_options & TL_OPTION_IGNORE_LEAVES; | |
| 7048 | 11757721 | ptr->set_derived_query_expression(table_name->sel); | |
| 7049 | |||
| 7050 |
6/6✓ Branch 0 taken 11513965 times.
✓ Branch 1 taken 243738 times.
✓ Branch 2 taken 11505978 times.
✓ Branch 3 taken 8259 times.
✓ Branch 4 taken 631735 times.
✓ Branch 5 taken 11126031 times.
|
23263316 | if (!ptr->is_derived() && !ptr->is_table_function() && |
| 7051 |
3/4✓ Branch 0 taken 11505769 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 631735 times.
✓ Branch 3 taken 10874034 times.
|
11505978 | is_infoschema_db(ptr->db, ptr->db_length)) { |
| 7052 | 631735 | dd::info_schema::convert_table_name_case( | |
| 7053 |
1/2✓ Branch 0 taken 631734 times.
✗ Branch 1 not taken.
|
631735 | const_cast<char *>(ptr->db), const_cast<char *>(ptr->table_name)); |
| 7054 | |||
| 7055 | 631734 | bool hidden_system_view = false; | |
| 7056 |
2/4✓ Branch 0 taken 631734 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 631735 times.
✗ Branch 3 not taken.
|
631734 | ptr->is_system_view = dd::get_dictionary()->is_system_view_name( |
| 7057 | ptr->db, ptr->table_name, &hidden_system_view); | ||
| 7058 | |||
| 7059 | ST_SCHEMA_TABLE *schema_table; | ||
| 7060 |
2/2✓ Branch 0 taken 16418 times.
✓ Branch 1 taken 615317 times.
|
631735 | if (ptr->updating && |
| 7061 | /* Special cases which are processed by commands itself */ | ||
| 7062 |
2/2✓ Branch 0 taken 16416 times.
✓ Branch 1 taken 2 times.
|
16418 | lex->sql_command != SQLCOM_CHECK && |
| 7063 |
2/2✓ Branch 0 taken 16415 times.
✓ Branch 1 taken 1 times.
|
16416 | lex->sql_command != SQLCOM_CHECKSUM && |
| 7064 |
4/4✓ Branch 0 taken 16139 times.
✓ Branch 1 taken 276 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 16134 times.
|
16415 | !(lex->sql_command == SQLCOM_CREATE_VIEW && ptr->is_system_view)) { |
| 7065 |
1/2✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 | my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), |
| 7066 |
1/2✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 | thd->security_context()->priv_user().str, |
| 7067 |
1/2✓ Branch 0 taken 281 times.
✗ Branch 1 not taken.
|
281 | thd->security_context()->priv_host().str, |
| 7068 | INFORMATION_SCHEMA_NAME.str); | ||
| 7069 | 997 | return nullptr; | |
| 7070 | } | ||
| 7071 |
2/2✓ Branch 0 taken 383882 times.
✓ Branch 1 taken 247572 times.
|
631454 | if (ptr->is_system_view) { |
| 7072 |
2/2✓ Branch 0 taken 362525 times.
✓ Branch 1 taken 21357 times.
|
383882 | if (thd->lex->sql_command != SQLCOM_CREATE_VIEW) { |
| 7073 | /* | ||
| 7074 | Stop users from using hidden system views, unless | ||
| 7075 | it is used by SHOW commands. | ||
| 7076 | */ | ||
| 7077 |
5/6✓ Branch 0 taken 362525 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1037 times.
✓ Branch 3 taken 361488 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 362524 times.
|
363562 | if (thd->lex->query_block && hidden_system_view && |
| 7078 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1036 times.
|
1037 | !(thd->lex->query_block->active_options() & |
| 7079 | OPTION_SELECT_FOR_SHOW)) { | ||
| 7080 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | my_error(ER_NO_SYSTEM_VIEW_ACCESS, MYF(0), ptr->table_name); |
| 7081 | 1 | return nullptr; | |
| 7082 | } | ||
| 7083 | |||
| 7084 | /* | ||
| 7085 | Stop users from accessing I_S.FILES if they do not have | ||
| 7086 | PROCESS privilege. | ||
| 7087 | */ | ||
| 7088 |
4/4✓ Branch 0 taken 26840 times.
✓ Branch 1 taken 335684 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 362519 times.
|
389364 | if (!strcmp(ptr->table_name, "FILES") && |
| 7089 |
3/4✓ Branch 0 taken 26840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 26835 times.
|
26840 | check_global_access(thd, PROCESS_ACL)) |
| 7090 | 5 | return nullptr; | |
| 7091 | } | ||
| 7092 | } else { | ||
| 7093 |
1/2✓ Branch 0 taken 247572 times.
✗ Branch 1 not taken.
|
247572 | schema_table = find_schema_table(thd, ptr->table_name); |
| 7094 | /* | ||
| 7095 | Report an error | ||
| 7096 | if hidden schema table name is used in the statement other than | ||
| 7097 | SHOW statement OR | ||
| 7098 | if unknown schema table is used in the statement other than | ||
| 7099 | SHOW CREATE VIEW statement. | ||
| 7100 | Invalid view warning is reported for SHOW CREATE VIEW statement in | ||
| 7101 | the table open stage. | ||
| 7102 | */ | ||
| 7103 | 248282 | if ((!schema_table && | |
| 7104 |
2/4✓ Branch 0 taken 710 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 710 times.
|
710 | !(thd->query_plan.get_command() == SQLCOM_SHOW_CREATE && |
| 7105 |
5/10✓ Branch 0 taken 710 times.
✓ Branch 1 taken 246862 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 246862 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 710 times.
✓ Branch 9 taken 246862 times.
|
495144 | thd->query_plan.get_lex()->only_view)) || |
| 7106 |
2/2✓ Branch 0 taken 197 times.
✓ Branch 1 taken 246665 times.
|
246862 | (schema_table && schema_table->hidden && |
| 7107 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 197 times.
|
197 | (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)) { |
| 7108 |
1/2✓ Branch 0 taken 710 times.
✗ Branch 1 not taken.
|
710 | my_error(ER_UNKNOWN_TABLE, MYF(0), ptr->table_name, |
| 7109 | INFORMATION_SCHEMA_NAME.str); | ||
| 7110 | 710 | return nullptr; | |
| 7111 | } | ||
| 7112 | |||
| 7113 |
1/2✓ Branch 0 taken 246862 times.
✗ Branch 1 not taken.
|
246862 | if (schema_table) { |
| 7114 | 246862 | ptr->schema_table = schema_table; | |
| 7115 | } | ||
| 7116 | } | ||
| 7117 | } | ||
| 7118 | |||
| 7119 | 11756769 | ptr->cacheable_table = true; | |
| 7120 | 11756769 | ptr->index_hints = index_hints_arg; | |
| 7121 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11756769 times.
|
11756769 | ptr->option = option ? option->str : nullptr; |
| 7122 | /* check that used name is unique */ | ||
| 7123 |
2/2✓ Branch 0 taken 11649971 times.
✓ Branch 1 taken 106798 times.
|
11756769 | if (lock_type != TL_IGNORE) { |
| 7124 | 11649971 | TABLE_LIST *first_table = table_list.first; | |
| 7125 |
2/2✓ Branch 0 taken 153664 times.
✓ Branch 1 taken 11496307 times.
|
11649971 | if (lex->sql_command == SQLCOM_CREATE_VIEW) |
| 7126 |
2/2✓ Branch 0 taken 73514 times.
✓ Branch 1 taken 80150 times.
|
153664 | first_table = first_table ? first_table->next_local : nullptr; |
| 7127 |
2/2✓ Branch 0 taken 16205616 times.
✓ Branch 1 taken 11649962 times.
|
27855578 | for (TABLE_LIST *tables = first_table; tables; |
| 7128 | 16205607 | tables = tables->next_local) { | |
| 7129 |
5/6✓ Branch 0 taken 16205615 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43 times.
✓ Branch 3 taken 16205572 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 16205607 times.
|
16205659 | if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) && |
| 7130 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 35 times.
|
43 | !strcmp(ptr->db, tables->db)) { |
| 7131 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */ |
| 7132 | 8 | return nullptr; /* purecov: tested */ | |
| 7133 | } | ||
| 7134 | } | ||
| 7135 | } | ||
| 7136 | /* Store the table reference preceding the current one. */ | ||
| 7137 |
2/2✓ Branch 0 taken 2708352 times.
✓ Branch 1 taken 9048408 times.
|
11756760 | if (table_list.elements > 0) { |
| 7138 | /* | ||
| 7139 | table_list.next points to the last inserted TABLE_LIST->next_local' | ||
| 7140 | element | ||
| 7141 | We don't use the offsetof() macro here to avoid warnings from gcc | ||
| 7142 | */ | ||
| 7143 | 2708352 | previous_table_ref = | |
| 7144 | (TABLE_LIST *)((char *)table_list.next - | ||
| 7145 | ((char *)&(ptr->next_local) - (char *)ptr)); | ||
| 7146 | /* | ||
| 7147 | Set next_name_resolution_table of the previous table reference to point | ||
| 7148 | to the current table reference. In effect the list | ||
| 7149 | TABLE_LIST::next_name_resolution_table coincides with | ||
| 7150 | TABLE_LIST::next_local. Later this may be changed in | ||
| 7151 | store_top_level_join_columns() for NATURAL/USING joins. | ||
| 7152 | */ | ||
| 7153 | 2708352 | previous_table_ref->next_name_resolution_table = ptr; | |
| 7154 | } | ||
| 7155 | |||
| 7156 | /* | ||
| 7157 | Link the current table reference in a local list (list for current select). | ||
| 7158 | Notice that as a side effect here we set the next_local field of the | ||
| 7159 | previous table reference to 'ptr'. Here we also add one element to the | ||
| 7160 | list 'table_list'. | ||
| 7161 | */ | ||
| 7162 | 11756760 | table_list.link_in_list(ptr, &ptr->next_local); | |
| 7163 | 11756140 | ptr->next_name_resolution_table = nullptr; | |
| 7164 | 11756140 | ptr->partition_names = partition_names; | |
| 7165 | /* Link table in global list (all used tables) */ | ||
| 7166 | 11756140 | lex->add_to_query_tables(ptr); | |
| 7167 | |||
| 7168 | // Pure table aliases do not need to be locked: | ||
| 7169 |
2/2✓ Branch 0 taken 11754673 times.
✓ Branch 1 taken 1558 times.
|
11756231 | if (!(table_options & TL_OPTION_ALIAS)) { |
| 7170 |
1/2✓ Branch 0 taken 11755859 times.
✗ Branch 1 not taken.
|
11754673 | MDL_REQUEST_INIT(&ptr->mdl_request, MDL_key::TABLE, ptr->db, |
| 7171 | ptr->table_name, mdl_type, MDL_TRANSACTION); | ||
| 7172 | } | ||
| 7173 |
2/2✓ Branch 0 taken 243788 times.
✓ Branch 1 taken 11513641 times.
|
11757417 | if (table_name->is_derived_table()) { |
| 7174 | 243788 | ptr->derived_key_list.clear(); | |
| 7175 | 243788 | derived_table_count++; | |
| 7176 | } | ||
| 7177 | |||
| 7178 | // Check access to DD tables. We must allow CHECK and ALTER TABLE | ||
| 7179 | // for the DDSE tables, since this is expected by the upgrade | ||
| 7180 | // client. We must also allow DDL access for the initialize thread, | ||
| 7181 | // since this thread is creating the I_S views. | ||
| 7182 | // Note that at this point, the mdl request for CREATE TABLE is still | ||
| 7183 | // MDL_SHARED, so we must explicitly check for SQLCOM_CREATE_TABLE. | ||
| 7184 |
1/2✓ Branch 0 taken 11756598 times.
✗ Branch 1 not taken.
|
11757429 | const dd::Dictionary *dictionary = dd::get_dictionary(); |
| 7185 |
3/4✓ Branch 0 taken 11756747 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1915178 times.
✓ Branch 3 taken 9840665 times.
|
23512590 | if (dictionary && |
| 7186 |
3/4✓ Branch 0 taken 11755992 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1915178 times.
✓ Branch 3 taken 9840814 times.
|
11756381 | !dictionary->is_dd_table_access_allowed( |
| 7187 |
6/6✓ Branch 0 taken 10718930 times.
✓ Branch 1 taken 1037844 times.
✓ Branch 2 taken 8804643 times.
✓ Branch 3 taken 1914292 times.
✓ Branch 4 taken 1956368 times.
✓ Branch 5 taken 6847877 times.
|
20560918 | thd->is_dd_system_thread() || thd->is_initialize_system_thread() || |
| 7188 | 8804643 | thd->is_server_upgrade_thread(), | |
| 7189 | 11756747 | (ptr->mdl_request.is_ddl_or_lock_tables_lock_request() || | |
| 7190 |
2/2✓ Branch 0 taken 635222 times.
✓ Branch 1 taken 10555080 times.
|
11190302 | (lex->sql_command == SQLCOM_CREATE_TABLE && |
| 7191 |
2/2✓ Branch 0 taken 621274 times.
✓ Branch 1 taken 13948 times.
|
635222 | ptr == lex->query_tables)) && |
| 7192 |
3/4✓ Branch 0 taken 11190302 times.
✓ Branch 1 taken 566371 times.
✓ Branch 2 taken 1187698 times.
✗ Branch 3 not taken.
|
24134673 | lex->sql_command != SQLCOM_CHECK && |
| 7193 |
2/2✓ Branch 0 taken 1107102 times.
✓ Branch 1 taken 80596 times.
|
1187698 | lex->sql_command != SQLCOM_ALTER_TABLE, |
| 7194 | ptr->db, ptr->db_length, ptr->table_name)) { | ||
| 7195 | // We must allow creation of the system views even for non-system | ||
| 7196 | // threads since this is expected by the mysql_upgrade utility. | ||
| 7197 | 3830360 | if (!(lex->sql_command == SQLCOM_CREATE_VIEW && | |
| 7198 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
8 | dd::get_dictionary()->is_system_view_name( |
| 7199 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | lex->query_tables->db, lex->query_tables->table_name)) |
| 7200 |
5/8✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1915174 times.
✓ Branch 2 taken 1915178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1915178 times.
✓ Branch 6 taken 1915178 times.
✗ Branch 7 not taken.
|
3830360 | && !(dd::get_dictionary()->is_system_view_name( |
| 7201 |
1/2✓ Branch 0 taken 1915178 times.
✗ Branch 1 not taken.
|
1915178 | lex->query_tables->db, lex->query_tables->table_name) |
| 7202 | ✗ | && DBUG_EVALUATE_IF("skip_dd_table_access_check", true, false)) | |
| 7203 | ) { | ||
| 7204 |
4/8✓ Branch 0 taken 1915178 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1915178 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1915178 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1915178 times.
✗ Branch 7 not taken.
|
1915178 | my_error(ER_NO_SYSTEM_TABLE_ACCESS, MYF(0), |
| 7205 |
1/2✓ Branch 0 taken 1915178 times.
✗ Branch 1 not taken.
|
1915178 | ER_THD_NONCONST(thd, dictionary->table_type_error_code( |
| 7206 | ptr->db, ptr->table_name)), | ||
| 7207 | ptr->db, ptr->table_name); | ||
| 7208 | // Take error handler into account to see if we should return. | ||
| 7209 |
3/4✓ Branch 0 taken 1915303 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 1915165 times.
|
1915178 | if (thd->is_error()) return nullptr; |
| 7210 | } | ||
| 7211 | } | ||
| 7212 | |||
| 7213 | 11755830 | return ptr; | |
| 7214 | 11757074 | } | |
| 7215 | |||
| 7216 | /** | ||
| 7217 | Initialize a new table list for a nested join. | ||
| 7218 | |||
| 7219 | The function initializes a structure of the TABLE_LIST type | ||
| 7220 | for a nested join. It sets up its nested join list as empty. | ||
| 7221 | The created structure is added to the front of the current | ||
| 7222 | join list in the Query_block object. Then the function | ||
| 7223 | changes the current nest level for joins to refer to the newly | ||
| 7224 | created empty list after having saved the info on the old level | ||
| 7225 | in the initialized structure. | ||
| 7226 | |||
| 7227 | @param thd current thread | ||
| 7228 | |||
| 7229 | @retval | ||
| 7230 | 0 if success | ||
| 7231 | @retval | ||
| 7232 | 1 otherwise | ||
| 7233 | */ | ||
| 7234 | |||
| 7235 | 1783951 | bool Query_block::init_nested_join(THD *thd) { | |
| 7236 |
1/2✓ Branch 0 taken 1783951 times.
✗ Branch 1 not taken.
|
1783951 | DBUG_TRACE; |
| 7237 | |||
| 7238 |
1/2✓ Branch 0 taken 1783951 times.
✗ Branch 1 not taken.
|
1783951 | TABLE_LIST *const ptr = TABLE_LIST::new_nested_join( |
| 7239 | 1783951 | thd->mem_root, "(nested_join)", embedding, join_list, this); | |
| 7240 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1783951 times.
|
1783951 | if (ptr == nullptr) return true; |
| 7241 | |||
| 7242 |
1/2✓ Branch 0 taken 1783951 times.
✗ Branch 1 not taken.
|
1783951 | join_list->push_front(ptr); |
| 7243 | 1783951 | embedding = ptr; | |
| 7244 | 1783951 | join_list = &ptr->nested_join->join_list; | |
| 7245 | |||
| 7246 | 1783951 | return false; | |
| 7247 | 1783951 | } | |
| 7248 | |||
| 7249 | /** | ||
| 7250 | End a nested join table list. | ||
| 7251 | |||
| 7252 | The function returns to the previous join nest level. | ||
| 7253 | If the current level contains only one member, the function | ||
| 7254 | moves it one level up, eliminating the nest. | ||
| 7255 | |||
| 7256 | @return | ||
| 7257 | - Pointer to TABLE_LIST element added to the total table list, if success | ||
| 7258 | - 0, otherwise | ||
| 7259 | */ | ||
| 7260 | |||
| 7261 | 1782830 | TABLE_LIST *Query_block::end_nested_join() { | |
| 7262 | TABLE_LIST *ptr; | ||
| 7263 | NESTED_JOIN *nested_join; | ||
| 7264 |
1/2✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
|
1782830 | DBUG_TRACE; |
| 7265 | |||
| 7266 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1782830 times.
|
1782830 | assert(embedding); |
| 7267 | 1782830 | ptr = embedding; | |
| 7268 | 1782830 | join_list = ptr->join_list; | |
| 7269 | 1782830 | embedding = ptr->embedding; | |
| 7270 | 1782830 | nested_join = ptr->nested_join; | |
| 7271 |
1/2✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
|
1782830 | if (nested_join->join_list.size() == 1) { |
| 7272 |
1/2✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
|
1782830 | TABLE_LIST *embedded = nested_join->join_list.front(); |
| 7273 |
1/2✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
|
1782830 | join_list->pop_front(); |
| 7274 | 1782830 | embedded->join_list = join_list; | |
| 7275 | 1782830 | embedded->embedding = embedding; | |
| 7276 |
1/2✓ Branch 0 taken 1782830 times.
✗ Branch 1 not taken.
|
1782830 | join_list->push_front(embedded); |
| 7277 | 1782830 | ptr = embedded; | |
| 7278 | ✗ | } else if (nested_join->join_list.empty()) { | |
| 7279 | ✗ | join_list->pop_front(); | |
| 7280 | ✗ | ptr = nullptr; // return value | |
| 7281 | } | ||
| 7282 | 1782830 | return ptr; | |
| 7283 | 1782830 | } | |
| 7284 | |||
| 7285 | /** | ||
| 7286 | Plumbing for nest_last_join, q.v. | ||
| 7287 | */ | ||
| 7288 | 1912128 | TABLE_LIST *nest_join(THD *thd, Query_block *select, TABLE_LIST *embedding, | |
| 7289 | mem_root_deque<TABLE_LIST *> *jlist, size_t table_cnt, | ||
| 7290 | const char *legend) { | ||
| 7291 |
1/2✓ Branch 0 taken 1912129 times.
✗ Branch 1 not taken.
|
1912128 | DBUG_TRACE; |
| 7292 | |||
| 7293 |
1/2✓ Branch 0 taken 1912129 times.
✗ Branch 1 not taken.
|
1912129 | TABLE_LIST *const ptr = TABLE_LIST::new_nested_join(thd->mem_root, legend, |
| 7294 | 1912129 | embedding, jlist, select); | |
| 7295 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1912129 times.
|
1912129 | if (ptr == nullptr) return nullptr; |
| 7296 | |||
| 7297 | 1912129 | mem_root_deque<TABLE_LIST *> *const embedded_list = | |
| 7298 | 1912129 | &ptr->nested_join->join_list; | |
| 7299 | |||
| 7300 |
2/2✓ Branch 0 taken 3824372 times.
✓ Branch 1 taken 1912129 times.
|
5736501 | for (uint i = 0; i < table_cnt; i++) { |
| 7301 |
1/2✓ Branch 0 taken 3824372 times.
✗ Branch 1 not taken.
|
3824372 | TABLE_LIST *table = jlist->front(); |
| 7302 |
1/2✓ Branch 0 taken 3824372 times.
✗ Branch 1 not taken.
|
3824372 | jlist->pop_front(); |
| 7303 | 3824372 | table->join_list = embedded_list; | |
| 7304 | 3824372 | table->embedding = ptr; | |
| 7305 |
1/2✓ Branch 0 taken 3824372 times.
✗ Branch 1 not taken.
|
3824372 | embedded_list->push_back(table); |
| 7306 |
2/2✓ Branch 0 taken 14168 times.
✓ Branch 1 taken 3810204 times.
|
3824372 | if (table->natural_join) ptr->is_natural_join = true; |
| 7307 | } | ||
| 7308 |
1/2✓ Branch 0 taken 1912129 times.
✗ Branch 1 not taken.
|
1912129 | jlist->push_front(ptr); |
| 7309 | |||
| 7310 | 1912129 | return ptr; | |
| 7311 | 1912129 | } | |
| 7312 | |||
| 7313 | /** | ||
| 7314 | Nest last join operations. | ||
| 7315 | |||
| 7316 | The function nest last table_cnt join operations as if they were | ||
| 7317 | the components of a cross join operation. | ||
| 7318 | |||
| 7319 | @param thd current thread | ||
| 7320 | @param table_cnt 2 for regular joins: t1 JOIN t2. | ||
| 7321 | N for the MySQL join-like extension: (t1, t2, ... tN). | ||
| 7322 | |||
| 7323 | @return Pointer to TABLE_LIST element created for the new nested join | ||
| 7324 | @retval | ||
| 7325 | 0 Error | ||
| 7326 | */ | ||
| 7327 | |||
| 7328 | 1912083 | TABLE_LIST *Query_block::nest_last_join(THD *thd, size_t table_cnt) { | |
| 7329 | 1912083 | return nest_join(thd, this, embedding, join_list, table_cnt, | |
| 7330 | 1912084 | "(nest_last_join)"); | |
| 7331 | } | ||
| 7332 | |||
| 7333 | /** | ||
| 7334 | Add a table to the current join list. | ||
| 7335 | |||
| 7336 | The function puts a table in front of the current join list | ||
| 7337 | of Query_block object. | ||
| 7338 | Thus, joined tables are put into this list in the reverse order | ||
| 7339 | (the most outer join operation follows first). | ||
| 7340 | |||
| 7341 | @param table The table to add. | ||
| 7342 | |||
| 7343 | @returns false if success, true if error (OOM). | ||
| 7344 | */ | ||
| 7345 | |||
| 7346 | 4804449 | bool Query_block::add_joined_table(TABLE_LIST *table) { | |
| 7347 |
1/2✓ Branch 0 taken 4804461 times.
✗ Branch 1 not taken.
|
4804449 | DBUG_TRACE; |
| 7348 |
1/2✓ Branch 0 taken 4804447 times.
✗ Branch 1 not taken.
|
4804461 | join_list->push_front(table); |
| 7349 | 4804447 | table->join_list = join_list; | |
| 7350 | 4804447 | table->embedding = embedding; | |
| 7351 | 4804462 | return false; | |
| 7352 | 4804447 | } | |
| 7353 | |||
| 7354 | 5030692 | void Query_block::set_lock_for_table(const Lock_descriptor &descriptor, | |
| 7355 | TABLE_LIST *table) { | ||
| 7356 | 5030692 | thr_lock_type lock_type = descriptor.type; | |
| 7357 | 5030692 | bool for_update = lock_type >= TL_READ_NO_INSERT; | |
| 7358 | 5030692 | enum_mdl_type mdl_type = mdl_type_for_dml(lock_type); | |
| 7359 |
1/2✓ Branch 0 taken 5031329 times.
✗ Branch 1 not taken.
|
5031019 | DBUG_TRACE; |
| 7360 |
5/8✓ Branch 0 taken 5031132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5031189 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 5031176 times.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
|
5031329 | DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type, for_update)); |
| 7361 | 5031189 | table->set_lock(descriptor); | |
| 7362 | 5031197 | table->updating = for_update; | |
| 7363 | 5031197 | table->mdl_request.set_type(mdl_type); | |
| 7364 | 5030656 | } | |
| 7365 | |||
| 7366 | /** | ||
| 7367 | Set lock for all tables in current query block. | ||
| 7368 | |||
| 7369 | @param lock_type Lock to set for tables. | ||
| 7370 | |||
| 7371 | @note | ||
| 7372 | If the lock is a write lock, then tables->updating is set to true. | ||
| 7373 | This is to get tables_ok to know that the table is being updated by the | ||
| 7374 | query. | ||
| 7375 | Sets the type of metadata lock to request according to lock_type. | ||
| 7376 | */ | ||
| 7377 | 4964910 | void Query_block::set_lock_for_tables(thr_lock_type lock_type) { | |
| 7378 |
1/2✓ Branch 0 taken 4965892 times.
✗ Branch 1 not taken.
|
4964910 | DBUG_TRACE; |
| 7379 |
5/8✓ Branch 0 taken 4965720 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4965752 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 4965739 times.
✓ Branch 6 taken 47 times.
✗ Branch 7 not taken.
|
4965892 | DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type, |
| 7380 | lock_type >= TL_READ_NO_INSERT)); | ||
| 7381 |
2/2✓ Branch 0 taken 5028988 times.
✓ Branch 1 taken 4966679 times.
|
9995667 | for (TABLE_LIST *table = table_list.first; table; table = table->next_local) |
| 7382 |
1/2✓ Branch 0 taken 5029881 times.
✗ Branch 1 not taken.
|
5028988 | set_lock_for_table({lock_type, THR_WAIT}, table); |
| 7383 | 4966679 | } | |
| 7384 | |||
| 7385 | /** | ||
| 7386 | Create a fake Query_block for a unit. | ||
| 7387 | |||
| 7388 | The method create a fake Query_block object for a unit. | ||
| 7389 | This object is created for any union construct containing a union | ||
| 7390 | operation and also for any single select union construct of the form | ||
| 7391 | @verbatim | ||
| 7392 | (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ... | ||
| 7393 | @endverbatim | ||
| 7394 | or of the form | ||
| 7395 | @verbatim | ||
| 7396 | (SELECT ... ORDER BY LIMIT n) ORDER BY ... | ||
| 7397 | @endverbatim | ||
| 7398 | |||
| 7399 | @param thd thread handle | ||
| 7400 | |||
| 7401 | @note | ||
| 7402 | The object is used to retrieve rows from the temporary table | ||
| 7403 | where the result on the union is obtained. | ||
| 7404 | |||
| 7405 | @retval | ||
| 7406 | 1 on failure to create the object | ||
| 7407 | @retval | ||
| 7408 | 0 on success | ||
| 7409 | */ | ||
| 7410 | |||
| 7411 | 21792 | bool Query_expression::add_fake_query_block(THD *thd) { | |
| 7412 | 21792 | Query_block *first_qb = first_query_block(); | |
| 7413 |
1/2✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
|
21792 | DBUG_TRACE; |
| 7414 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21792 times.
|
21792 | assert(!fake_query_block); |
| 7415 | |||
| 7416 |
2/4✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21792 times.
|
21792 | if (!(fake_query_block = thd->lex->new_empty_query_block())) |
| 7417 | ✗ | return true; /* purecov: inspected */ | |
| 7418 |
1/2✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
|
21792 | fake_query_block->include_standalone(this, &fake_query_block); |
| 7419 | 21792 | fake_query_block->select_number = INT_MAX; | |
| 7420 | 21792 | fake_query_block->linkage = GLOBAL_OPTIONS_TYPE; | |
| 7421 | 21792 | fake_query_block->select_limit = nullptr; | |
| 7422 | |||
| 7423 |
1/2✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
|
21792 | fake_query_block->set_context(first_qb->context.outer_context); |
| 7424 | |||
| 7425 | /* allow item list resolving in fake select for ORDER BY */ | ||
| 7426 | 21792 | fake_query_block->context.resolve_in_select_list = true; | |
| 7427 | |||
| 7428 |
1/2✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
|
21792 | if (!is_union()) { |
| 7429 | /* | ||
| 7430 | This works only for | ||
| 7431 | (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m], | ||
| 7432 | (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m] | ||
| 7433 | just before the parser starts processing order_list | ||
| 7434 | */ | ||
| 7435 | 21792 | fake_query_block->no_table_names_allowed = true; | |
| 7436 | } | ||
| 7437 |
1/2✓ Branch 0 taken 21792 times.
✗ Branch 1 not taken.
|
21792 | thd->lex->pop_context(); |
| 7438 | 21792 | return false; | |
| 7439 | 21792 | } | |
| 7440 | |||
| 7441 | /** | ||
| 7442 | Push a new name resolution context for a JOIN ... ON clause to the | ||
| 7443 | context stack of a query block. | ||
| 7444 | |||
| 7445 | Create a new name resolution context for a JOIN ... ON clause, | ||
| 7446 | set the first and last leaves of the list of table references | ||
| 7447 | to be used for name resolution, and push the newly created | ||
| 7448 | context to the stack of contexts of the query. | ||
| 7449 | |||
| 7450 | @param pc current parse context | ||
| 7451 | @param left_op left operand of the JOIN | ||
| 7452 | @param right_op right operand of the JOIN | ||
| 7453 | |||
| 7454 | @retval | ||
| 7455 | false if all is OK | ||
| 7456 | @retval | ||
| 7457 | true if a memory allocation error occurred | ||
| 7458 | */ | ||
| 7459 | |||
| 7460 | 1885295 | bool push_new_name_resolution_context(Parse_context *pc, TABLE_LIST *left_op, | |
| 7461 | TABLE_LIST *right_op) { | ||
| 7462 | 1885295 | THD *thd = pc->thd; | |
| 7463 | Name_resolution_context *on_context; | ||
| 7464 |
3/6✓ Branch 0 taken 1885295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1885295 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1885295 times.
|
1885295 | if (!(on_context = new (thd->mem_root) Name_resolution_context)) return true; |
| 7465 | 1885295 | on_context->init(); | |
| 7466 | 1885295 | on_context->first_name_resolution_table = | |
| 7467 | 1885295 | left_op->first_leaf_for_name_resolution(); | |
| 7468 | 1885295 | on_context->last_name_resolution_table = | |
| 7469 | 1885295 | right_op->last_leaf_for_name_resolution(); | |
| 7470 | 1885295 | on_context->query_block = pc->select; | |
| 7471 | // Other tables in FROM clause of this JOIN are not visible: | ||
| 7472 | 1885295 | on_context->outer_context = thd->lex->current_context()->outer_context; | |
| 7473 | 1885295 | on_context->next_context = pc->select->first_context; | |
| 7474 | 1885295 | pc->select->first_context = on_context; | |
| 7475 | |||
| 7476 | 1885295 | return thd->lex->push_context(on_context); | |
| 7477 | } | ||
| 7478 | |||
| 7479 | /** | ||
| 7480 | Add an ON condition to the second operand of a JOIN ... ON. | ||
| 7481 | |||
| 7482 | Add an ON condition to the right operand of a JOIN ... ON clause. | ||
| 7483 | |||
| 7484 | @param b the second operand of a JOIN ... ON | ||
| 7485 | @param expr the condition to be added to the ON clause | ||
| 7486 | */ | ||
| 7487 | |||
| 7488 | 1900192 | void add_join_on(TABLE_LIST *b, Item *expr) { | |
| 7489 |
1/2✓ Branch 0 taken 1900192 times.
✗ Branch 1 not taken.
|
1900192 | if (expr) { |
| 7490 | 1900192 | b->set_join_cond_optim((Item *)1); // m_join_cond_optim is not ready | |
| 7491 |
2/2✓ Branch 0 taken 1898235 times.
✓ Branch 1 taken 1957 times.
|
1900192 | if (!b->join_cond()) |
| 7492 | 1898235 | b->set_join_cond(expr); | |
| 7493 | else { | ||
| 7494 | /* | ||
| 7495 | If called from the parser, this happens if you have both a | ||
| 7496 | right and left join. If called later, it happens if we add more | ||
| 7497 | than one condition to the ON clause. | ||
| 7498 | */ | ||
| 7499 |
2/4✓ Branch 0 taken 1957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1957 times.
✗ Branch 3 not taken.
|
1957 | b->set_join_cond(new Item_cond_and(b->join_cond(), expr)); |
| 7500 | } | ||
| 7501 | 1900192 | b->join_cond()->apply_is_true(); | |
| 7502 | } | ||
| 7503 | 1900192 | } | |
| 7504 | |||
| 7505 | 10 | const CHARSET_INFO *get_bin_collation(const CHARSET_INFO *cs) { | |
| 7506 | const CHARSET_INFO *ret = | ||
| 7507 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | get_charset_by_csname(cs->csname, MY_CS_BINSORT, MYF(0)); |
| 7508 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | if (ret) return ret; |
| 7509 | |||
| 7510 | char tmp[65]; | ||
| 7511 | ✗ | strmake(strmake(tmp, cs->csname, sizeof(tmp) - 4), STRING_WITH_LEN("_bin")); | |
| 7512 | ✗ | my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp); | |
| 7513 | ✗ | return nullptr; | |
| 7514 | } | ||
| 7515 | |||
| 7516 | /** | ||
| 7517 | kill on thread. | ||
| 7518 | |||
| 7519 | @param thd Thread class | ||
| 7520 | @param id Thread id | ||
| 7521 | @param only_kill_query Should it kill the query or the connection | ||
| 7522 | |||
| 7523 | @note | ||
| 7524 | This is written such that we have a short lock on LOCK_thd_list | ||
| 7525 | */ | ||
| 7526 | |||
| 7527 | 2601 | static uint kill_one_thread(THD *thd, my_thread_id id, bool only_kill_query) { | |
| 7528 | 2601 | uint error = ER_NO_SUCH_THREAD; | |
| 7529 | 2601 | Find_thd_with_id find_thd_with_id(id, false); | |
| 7530 | |||
| 7531 |
1/2✓ Branch 0 taken 2601 times.
✗ Branch 1 not taken.
|
2601 | DBUG_TRACE; |
| 7532 |
3/8✓ Branch 0 taken 2601 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2601 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2601 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2601 | DBUG_PRINT("enter", ("id=%u only_kill=%d", id, only_kill_query)); |
| 7533 |
1/2✓ Branch 0 taken 2601 times.
✗ Branch 1 not taken.
|
2601 | THD_ptr tmp = Global_THD_manager::get_instance()->find_thd(&find_thd_with_id); |
| 7534 | 2601 | Security_context *sctx = thd->security_context(); | |
| 7535 |
2/2✓ Branch 0 taken 2572 times.
✓ Branch 1 taken 29 times.
|
2601 | if (tmp) { |
| 7536 | /* | ||
| 7537 | If we're SUPER, we can KILL anything, including system-threads. | ||
| 7538 | No further checks. | ||
| 7539 | |||
| 7540 | KILLer: thd->m_security_ctx->user could in theory be NULL while | ||
| 7541 | we're still in "unauthenticated" state. This is a theoretical | ||
| 7542 | case (the code suggests this could happen, so we play it safe). | ||
| 7543 | |||
| 7544 | KILLee: tmp->m_security_ctx->user will be NULL for system threads. | ||
| 7545 | We need to check so Jane Random User doesn't crash the server | ||
| 7546 | when trying to kill a) system threads or b) unauthenticated users' | ||
| 7547 | threads (Bug#43748). | ||
| 7548 | |||
| 7549 | If user of both killer and killee are non-NULL, proceed with | ||
| 7550 | slayage if both are string-equal. | ||
| 7551 | */ | ||
| 7552 | |||
| 7553 |
1/2✓ Branch 0 taken 2572 times.
✗ Branch 1 not taken.
|
2572 | const bool is_utility_connection = acl_is_utility_user( |
| 7554 |
2/4✓ Branch 0 taken 2572 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2572 times.
✗ Branch 3 not taken.
|
2572 | tmp->m_security_ctx->user().str, tmp->m_security_ctx->host().str, |
| 7555 |
1/2✓ Branch 0 taken 2572 times.
✗ Branch 1 not taken.
|
2572 | tmp->m_security_ctx->ip().str); |
| 7556 | #ifdef WITH_WSREP | ||
| 7557 |
3/4✓ Branch 0 taken 2572 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 2567 times.
|
2572 | if (wsrep_thd_is_in_to_isolation(tmp.get(), false)) { |
| 7558 | /* There is nothing special about the use of ER_QUERY_INTERRUPTED, | ||
| 7559 | I just needed a different error code from ER_KILL_DENIED_ERROR. | ||
| 7560 | |||
| 7561 | See sql_kill() to see the other half of the error processing. | ||
| 7562 | */ | ||
| 7563 | 5 | error = ER_QUERY_INTERRUPTED; | |
| 7564 |
4/10✓ Branch 0 taken 2567 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2551 times.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
5134 | } else if ((((sctx->check_access(SUPER_ACL) || |
| 7565 |
1/2✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
|
44 | sctx->has_global_grant(STRING_WITH_LEN("CONNECTION_ADMIN")) |
| 7566 |
2/2✓ Branch 0 taken 29 times.
✓ Branch 1 taken 15 times.
|
44 | .first) && |
| 7567 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2551 times.
|
2552 | !is_utility_connection) || |
| 7568 |
3/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 10 times.
|
16 | sctx->user_matches(tmp->security_context())) && |
| 7569 |
9/12✓ Branch 0 taken 2567 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 2523 times.
✓ Branch 4 taken 2557 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2555 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 2551 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 2567 times.
✗ Branch 11 not taken.
|
7701 | !wsrep_thd_is_BF(tmp.get(), true) && !tmp->wsrep_applier) { |
| 7570 | #else | ||
| 7571 | if (((sctx->check_access(SUPER_ACL) || | ||
| 7572 | sctx->has_global_grant(STRING_WITH_LEN("CONNECTION_ADMIN")).first) && | ||
| 7573 | !is_utility_connection) || | ||
| 7574 | sctx->user_matches(tmp->security_context())) { | ||
| 7575 | #endif /* WITH_WSREP */ | ||
| 7576 | /* | ||
| 7577 | Process the kill: | ||
| 7578 | if thread is not already undergoing any kill connection. | ||
| 7579 | Killer must have SYSTEM_USER privilege iff killee has the same privilege | ||
| 7580 | privilege | ||
| 7581 | */ | ||
| 7582 |
1/2✓ Branch 0 taken 2551 times.
✗ Branch 1 not taken.
|
2551 | if (tmp->killed != THD::KILL_CONNECTION) { |
| 7583 |
8/10✓ Branch 0 taken 2551 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2414 times.
✓ Branch 3 taken 137 times.
✓ Branch 4 taken 2414 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 2396 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 2533 times.
|
2551 | if (tmp->is_system_user() && !thd->is_system_user()) { |
| 7584 | 18 | error = ER_KILL_DENIED_ERROR; | |
| 7585 | } else { | ||
| 7586 | #ifdef WITH_WSREP | ||
| 7587 |
3/4✓ Branch 0 taken 2507 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 2507 times.
✗ Branch 3 not taken.
|
2533 | DEBUG_SYNC(thd, "before_awake_no_mutex"); |
| 7588 |
2/6✗ Branch 0 not taken.
✓ Branch 1 taken 2533 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2533 times.
|
2533 | if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id()) { |
| 7589 | /* victim is in hit list already, bail out */ | ||
| 7590 | ✗ | WSREP_DEBUG("victim has wsrep aborter: %u, skipping awake()", | |
| 7591 | tmp->wsrep_aborter); | ||
| 7592 | ✗ | error = 0; | |
| 7593 | } else { | ||
| 7594 |
1/24✗ Branch 0 not taken.
✓ Branch 1 taken 2533 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
2533 | WSREP_DEBUG("kill_one_thread victim: %u aborter %u kill query %d", |
| 7595 | id, tmp->wsrep_aborter, only_kill_query); | ||
| 7596 | #endif /* WITH_WSREP */ | ||
| 7597 |
3/4✓ Branch 0 taken 199 times.
✓ Branch 1 taken 2334 times.
✓ Branch 2 taken 2533 times.
✗ Branch 3 not taken.
|
2533 | tmp->awake(only_kill_query ? THD::KILL_QUERY |
| 7598 | : THD::KILL_CONNECTION); | ||
| 7599 | 2533 | error = 0; | |
| 7600 | #ifdef WITH_WSREP | ||
| 7601 | } | ||
| 7602 | #endif /* WITH_WSREP */ | ||
| 7603 | } | ||
| 7604 | } else | ||
| 7605 | ✗ | error = 0; | |
| 7606 | } else | ||
| 7607 | 16 | error = ER_KILL_DENIED_ERROR; | |
| 7608 | } | ||
| 7609 |
3/4✓ Branch 0 taken 2562 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 2562 times.
✗ Branch 3 not taken.
|
2601 | DEBUG_SYNC(thd, "kill_thd_end"); |
| 7610 |
3/8✓ Branch 0 taken 2601 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2601 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2601 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2601 | DBUG_PRINT("exit", ("%d", error)); |
| 7611 | 2601 | return error; | |
| 7612 | 2601 | } | |
| 7613 | |||
| 7614 | #ifdef WITH_WSREP | ||
| 7615 | 165 | static void wsrep_prepare_for_autocommit_retry(THD *thd, const char *rawbuf, | |
| 7616 | uint length, | ||
| 7617 | Parser_state *parser_state) { | ||
| 7618 | 165 | thd->clear_error(); | |
| 7619 | 165 | thd->wsrep_aborter = 0; | |
| 7620 | 165 | close_thread_tables(thd); | |
| 7621 | /* Ensure the gtid is resetted on query retry so retry attempt operates | ||
| 7622 | with same flow as normal attempt waiting for sync_wait if needed. */ | ||
| 7623 | 165 | thd->wsrep_cs().reset_sync_wait_gtid(); | |
| 7624 | 165 | thd->wsrep_retry_counter++; // grow | |
| 7625 | 165 | wsrep_copy_query(thd); | |
| 7626 | 165 | thd->set_time(); | |
| 7627 | 165 | parser_state->reset(rawbuf, length); | |
| 7628 | |||
| 7629 | /* PSI end */ | ||
| 7630 | 165 | MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); | |
| 7631 | 165 | thd->m_statement_psi = NULL; | |
| 7632 | 165 | thd->m_digest = NULL; | |
| 7633 | |||
| 7634 | /* SHOW PROFILE end */ | ||
| 7635 | #if defined(ENABLED_PROFILING) | ||
| 7636 | 165 | thd->profiling->finish_current_query(); | |
| 7637 | #endif | ||
| 7638 | |||
| 7639 | /* SHOW PROFILE begin */ | ||
| 7640 | #if defined(ENABLED_PROFILING) | ||
| 7641 | 165 | thd->profiling->start_new_query("continuing"); | |
| 7642 | 165 | thd->profiling->set_query_source(rawbuf, length); | |
| 7643 | #endif | ||
| 7644 | |||
| 7645 | /* Performance Schema Interface instrumentation, begin */ | ||
| 7646 | 165 | thd->m_statement_psi = MYSQL_REFINE_STATEMENT( | |
| 7647 | thd->m_statement_psi, com_statement_info[thd->get_command()].m_key); | ||
| 7648 | 165 | MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query().str, | |
| 7649 | thd->query().length); | ||
| 7650 | |||
| 7651 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 165 times.
|
165 | assert(thd->wsrep_trx().active() == false); |
| 7652 | 165 | thd->wsrep_cs().reset_error(); | |
| 7653 | 165 | thd->set_query_id(next_query_id()); | |
| 7654 | 165 | } | |
| 7655 | |||
| 7656 | 274 | static bool wsrep_should_retry_in_autocommit(const THD *thd) { | |
| 7657 | /* | ||
| 7658 | We are here could mean that the query resulted in a cluster-wide | ||
| 7659 | conflict and had to be aborted. While it happened, it is possible that | ||
| 7660 | the client may have already received partial data from server and may | ||
| 7661 | have been waiting for the OK/EOF packet (usually sent by | ||
| 7662 | THD::send_statement_status() in dispatch_command()) to report it to the | ||
| 7663 | user. | ||
| 7664 | |||
| 7665 | When retry is performed in such a case, the server shall start sending | ||
| 7666 | result and field metadata once again and this would cause the client | ||
| 7667 | program to receive unexpected metadata information in place of an | ||
| 7668 | OK/EOF packet and thus causes the client to error out with Malformed | ||
| 7669 | packet error. | ||
| 7670 | |||
| 7671 | So, we avoid retries for such queries that return result set to client, | ||
| 7672 | but cannot be run in TOI and can be killed by a TOI. | ||
| 7673 | |||
| 7674 | As of now, we only do this check for CHECK TABLE and SELECT, and if the | ||
| 7675 | same symptom is found for other commands, then please add it to the | ||
| 7676 | below list. | ||
| 7677 | */ | ||
| 7678 |
3/3✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 268 times.
|
274 | switch (thd->lex->sql_command) { |
| 7679 | 1 | case SQLCOM_CHECK: | |
| 7680 | case SQLCOM_SELECT: | ||
| 7681 | 1 | return false; | |
| 7682 | 5 | case SQLCOM_ALTER_TABLE: { | |
| 7683 | 5 | return (thd->lex->alter_info->flags & Alter_info::ALTER_ADMIN_PARTITION | |
| 7684 | ? false | ||
| 7685 | 5 | : true); | |
| 7686 | } | ||
| 7687 | 268 | default: | |
| 7688 | 268 | return true; | |
| 7689 | } | ||
| 7690 | } | ||
| 7691 | |||
| 7692 | 162902 | static bool wsrep_dispatch_sql_command(THD *thd, const char *rawbuf, | |
| 7693 | uint length, Parser_state *parser_state, | ||
| 7694 | bool update_userstat) { | ||
| 7695 |
1/2✓ Branch 0 taken 162903 times.
✗ Branch 1 not taken.
|
162902 | DBUG_TRACE; |
| 7696 |
2/2✓ Branch 0 taken 151735 times.
✓ Branch 1 taken 11167 times.
|
314640 | bool is_autocommit = !thd->in_multi_stmt_transaction_mode() && |
| 7697 |
2/4✓ Branch 0 taken 151737 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 151737 times.
✗ Branch 3 not taken.
|
314639 | wsrep_read_only_option(thd, thd->lex->query_tables); |
| 7698 | bool retry_autocommit; | ||
| 7699 | |||
| 7700 |
2/2✓ Branch 0 taken 165 times.
✓ Branch 1 taken 162901 times.
|
163066 | do { |
| 7701 | 163069 | retry_autocommit = false; | |
| 7702 |
1/2✓ Branch 0 taken 163066 times.
✗ Branch 1 not taken.
|
163069 | dispatch_sql_command(thd, parser_state, update_userstat); |
| 7703 | |||
| 7704 | /* | ||
| 7705 | Convert all ER_QUERY_INTERRUPTED errors to ER_LOCK_DEADLOCK | ||
| 7706 | if the transaction was BF aborted. This can happen when the | ||
| 7707 | transaction is being BF aborted via thd->awake() while it is | ||
| 7708 | still executing. | ||
| 7709 | |||
| 7710 | Note that this must be done before wsrep_after_statement() call | ||
| 7711 | since it clears the transaction for autocommit queries. | ||
| 7712 | */ | ||
| 7713 |
2/2✓ Branch 0 taken 7317 times.
✓ Branch 1 taken 192 times.
|
170575 | if (((thd->get_stmt_da()->is_error() && |
| 7714 | 7509 | thd->get_stmt_da()->mysql_errno() == ER_QUERY_INTERRUPTED) || | |
| 7715 |
8/8✓ Branch 0 taken 7509 times.
✓ Branch 1 taken 155557 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 162864 times.
✓ Branch 4 taken 191 times.
✓ Branch 5 taken 11 times.
✓ Branch 6 taken 191 times.
✓ Branch 7 taken 162875 times.
|
170585 | !thd->get_stmt_da()->is_set()) && |
| 7716 | 202 | thd->wsrep_trx().bf_aborted()) { | |
| 7717 |
1/26✗ Branch 0 not taken.
✓ Branch 1 taken 191 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
|
191 | WSREP_DEBUG("overriding error: %d with DEADLOCK", |
| 7718 | (thd->get_stmt_da()->is_error()) | ||
| 7719 | ? thd->get_stmt_da()->mysql_errno() | ||
| 7720 | : 0); | ||
| 7721 | |||
| 7722 | 191 | thd->killed = THD::NOT_KILLED; | |
| 7723 |
1/2✓ Branch 0 taken 191 times.
✗ Branch 1 not taken.
|
191 | wsrep_override_error(thd, ER_LOCK_DEADLOCK); |
| 7724 | } | ||
| 7725 | |||
| 7726 |
7/8✓ Branch 0 taken 163066 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 334 times.
✓ Branch 3 taken 162732 times.
✓ Branch 4 taken 274 times.
✓ Branch 5 taken 60 times.
✓ Branch 6 taken 274 times.
✓ Branch 7 taken 162792 times.
|
163066 | if (wsrep_after_statement(thd) && is_autocommit) { |
| 7727 |
1/2✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
|
274 | thd->reset_for_next_command(); |
| 7728 | 274 | thd->killed = THD::NOT_KILLED; | |
| 7729 |
5/6✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 272 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 165 times.
✓ Branch 5 taken 109 times.
|
546 | if (is_autocommit && wsrep_should_retry_in_autocommit(thd) && |
| 7730 |
2/2✓ Branch 0 taken 165 times.
✓ Branch 1 taken 107 times.
|
272 | thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit) { |
| 7731 |
5/8✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 65 times.
✓ Branch 3 taken 100 times.
✓ Branch 4 taken 65 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 65 times.
|
165 | DBUG_EXECUTE_IF("sync.wsrep_retry_autocommit", { |
| 7732 | const char act[] = | ||
| 7733 | "now " | ||
| 7734 | "SIGNAL wsrep_retry_autocommit_reached " | ||
| 7735 | "WAIT_FOR wsrep_retry_autocommit_continue"; | ||
| 7736 | assert(!debug_sync_set_action(thd, STRING_WITH_LEN(act))); | ||
| 7737 | }); | ||
| 7738 |
1/40✗ Branch 0 not taken.
✓ Branch 1 taken 165 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
165 | WSREP_DEBUG("wsrep retrying AC query: %lu %s", |
| 7739 | thd->wsrep_retry_counter, WSREP_QUERY(thd)); | ||
| 7740 |
1/2✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
|
165 | wsrep_prepare_for_autocommit_retry(thd, rawbuf, length, parser_state); |
| 7741 | // if (thd->lex->explain) delete_explain_query(thd->lex); | ||
| 7742 | 165 | retry_autocommit = true; | |
| 7743 | } else { | ||
| 7744 |
1/42✗ Branch 0 not taken.
✓ Branch 1 taken 109 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
|
109 | WSREP_DEBUG("%s, thd: %u is_AC: %d, retry: %lu - %lu SQL: %s", |
| 7745 | wsrep_thd_transaction_state_str(thd), thd->thread_id(), | ||
| 7746 | is_autocommit, thd->wsrep_retry_counter, | ||
| 7747 | thd->variables.wsrep_retry_autocommit, WSREP_QUERY(thd)); | ||
| 7748 |
1/2✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
|
109 | my_error(ER_LOCK_DEADLOCK, MYF(0)); |
| 7749 | 108 | thd->killed = THD::NOT_KILLED; | |
| 7750 | 109 | thd->wsrep_retry_counter = 0; // reset | |
| 7751 | } | ||
| 7752 | } else { | ||
| 7753 | 162792 | thd->wsrep_retry_counter = 0; | |
| 7754 | } | ||
| 7755 | } while (retry_autocommit); | ||
| 7756 | |||
| 7757 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 162852 times.
|
162901 | if (thd->wsrep_retry_query) { |
| 7758 |
1/28✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
49 | WSREP_DEBUG( |
| 7759 | "releasing retry_query: " | ||
| 7760 | "conf %s sent %d kill %d errno %d SQL %s", | ||
| 7761 | wsrep_thd_transaction_state_str(thd), thd->get_stmt_da()->is_sent(), | ||
| 7762 | thd->killed.load(), | ||
| 7763 | thd->get_stmt_da()->is_error() ? thd->get_stmt_da()->mysql_errno() : 0, | ||
| 7764 | thd->wsrep_retry_query); | ||
| 7765 |
1/2✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
|
49 | my_free(thd->wsrep_retry_query); |
| 7766 | 49 | thd->wsrep_retry_query = NULL; | |
| 7767 | 49 | thd->wsrep_retry_query_len = 0; | |
| 7768 | 49 | thd->wsrep_retry_command = COM_CONNECT; | |
| 7769 | } | ||
| 7770 | |||
| 7771 | #if 0 | ||
| 7772 | /* Keep this code here for easy validation. | ||
| 7773 | If there is multi-stmt transaction then transaction locks are present at this | ||
| 7774 | point. */ | ||
| 7775 | assert(!thd->mdl_context.has_stmt_locks()); | ||
| 7776 | assert(!thd->mdl_context.has_transactional_locks() || thd->in_multi_stmt_transaction_mode()); | ||
| 7777 | assert(!thd->mdl_context.has_explicit_locks()); | ||
| 7778 | #endif | ||
| 7779 | |||
| 7780 | 162900 | return false; | |
| 7781 | 162901 | } | |
| 7782 | #endif /* WITH_WSREP */ | ||
| 7783 | |||
| 7784 | /* | ||
| 7785 | kills a thread and sends response | ||
| 7786 | |||
| 7787 | SYNOPSIS | ||
| 7788 | sql_kill() | ||
| 7789 | thd Thread class | ||
| 7790 | id Thread id | ||
| 7791 | only_kill_query Should it kill the query or the connection | ||
| 7792 | */ | ||
| 7793 | |||
| 7794 | 2601 | static void sql_kill(THD *thd, my_thread_id id, bool only_kill_query) { | |
| 7795 | uint error; | ||
| 7796 |
2/2✓ Branch 0 taken 2533 times.
✓ Branch 1 taken 68 times.
|
2601 | if (!(error = kill_one_thread(thd, id, only_kill_query))) { |
| 7797 |
2/2✓ Branch 0 taken 2491 times.
✓ Branch 1 taken 42 times.
|
2533 | if (!thd->killed) my_ok(thd); |
| 7798 | } else | ||
| 7799 | #ifdef WITH_WSREP | ||
| 7800 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 63 times.
|
68 | if (error == ER_QUERY_INTERRUPTED) { |
| 7801 | 5 | my_printf_error(ER_KILL_DENIED_ERROR, | |
| 7802 | "The query is in TOI/NBO and cannot be killed", MYF(0)); | ||
| 7803 | } else | ||
| 7804 | #endif /* WITH_WSREP */ | ||
| 7805 | 63 | my_error(error, MYF(0), id); | |
| 7806 | 2601 | } | |
| 7807 | |||
| 7808 | /** | ||
| 7809 | This class implements callback function used by killall_non_super_threads | ||
| 7810 | to kill all threads that do not have the SUPER privilege | ||
| 7811 | */ | ||
| 7812 | |||
| 7813 | class Kill_non_super_conn : public Do_THD_Impl { | ||
| 7814 | private: | ||
| 7815 | /* THD of connected client. */ | ||
| 7816 | THD *m_client_thd; | ||
| 7817 | bool m_is_client_regular_user; | ||
| 7818 | |||
| 7819 | public: | ||
| 7820 | 35 | Kill_non_super_conn(THD *thd) : m_client_thd(thd) { | |
| 7821 |
8/18✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 5 times.
✓ Branch 10 taken 35 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 35 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
35 | assert(m_client_thd->security_context()->check_access(SUPER_ACL) || |
| 7822 | m_client_thd->security_context() | ||
| 7823 | ->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN")) | ||
| 7824 | .first); | ||
| 7825 |
1/2✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
|
35 | m_is_client_regular_user = !m_client_thd->is_system_user(); |
| 7826 | 35 | } | |
| 7827 | |||
| 7828 | 464 | void operator()(THD *thd_to_kill) override { | |
| 7829 | 464 | mysql_mutex_lock(&thd_to_kill->LOCK_thd_data); | |
| 7830 | |||
| 7831 | 464 | Security_context *sctx = thd_to_kill->security_context(); | |
| 7832 | |||
| 7833 | const bool is_utility_user = | ||
| 7834 | 464 | acl_is_utility_user(sctx->user().str, sctx->host().str, sctx->ip().str); | |
| 7835 | |||
| 7836 | /* Kill only if non-privileged thread and non slave thread. | ||
| 7837 | If an account has not yet been assigned to the security context of the | ||
| 7838 | thread we cannot tell if the account is super user or not. In this case | ||
| 7839 | we cannot kill that thread. In offline mode, after the account is | ||
| 7840 | assigned to this thread and it turns out it is not privileged user | ||
| 7841 | thread, the authentication for this thread will fail and the thread will | ||
| 7842 | be terminated. | ||
| 7843 | Additionally, client with SYSTEM_VARIABLES_ADMIN but not SYSTEM_USER | ||
| 7844 | privilege is not allowed to kill threads having SYSTEM_USER, | ||
| 7845 | but not CONNECTION_ADMIN privilege. | ||
| 7846 | */ | ||
| 7847 | const bool has_higher_privilege = | ||
| 7848 |
4/4✓ Branch 0 taken 13 times.
✓ Branch 1 taken 451 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 5 times.
|
464 | m_is_client_regular_user && thd_to_kill->is_system_user(); |
| 7849 |
1/2✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
|
716 | if (!thd_to_kill->is_connection_admin() && |
| 7850 | 252 | thd_to_kill->killed != THD::KILL_CONNECTION && | |
| 7851 |
10/10✓ Branch 0 taken 252 times.
✓ Branch 1 taken 212 times.
✓ Branch 2 taken 251 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 249 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 248 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 248 times.
✓ Branch 9 taken 216 times.
|
716 | !thd_to_kill->slave_thread && !has_higher_privilege && !is_utility_user) |
| 7852 | 248 | thd_to_kill->awake(THD::KILL_CONNECTION); | |
| 7853 | |||
| 7854 | 464 | mysql_mutex_unlock(&thd_to_kill->LOCK_thd_data); | |
| 7855 | 464 | } | |
| 7856 | }; | ||
| 7857 | |||
| 7858 | /* | ||
| 7859 | kills all the threads that do not have the | ||
| 7860 | SUPER privilege. | ||
| 7861 | |||
| 7862 | SYNOPSIS | ||
| 7863 | killall_non_super_threads() | ||
| 7864 | thd Thread class | ||
| 7865 | */ | ||
| 7866 | |||
| 7867 | 35 | void killall_non_super_threads(THD *thd) { | |
| 7868 |
1/2✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
|
35 | Kill_non_super_conn kill_non_super_conn(thd); |
| 7869 | 35 | Global_THD_manager *thd_manager = Global_THD_manager::get_instance(); | |
| 7870 |
1/2✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
|
35 | thd_manager->do_for_all_thd(&kill_non_super_conn); |
| 7871 | 35 | } | |
| 7872 | |||
| 7873 | /** | ||
| 7874 | prepares the index and data directory path. | ||
| 7875 | |||
| 7876 | @param thd Thread handle | ||
| 7877 | @param data_file_name Pathname for data directory | ||
| 7878 | @param index_file_name Pathname for index directory | ||
| 7879 | @param table_name Table name to be appended to the pathname | ||
| 7880 | specified | ||
| 7881 | |||
| 7882 | @return false success | ||
| 7883 | @return true An error occurred | ||
| 7884 | */ | ||
| 7885 | |||
| 7886 | 618791 | bool prepare_index_and_data_dir_path(THD *thd, const char **data_file_name, | |
| 7887 | const char **index_file_name, | ||
| 7888 | const char *table_name) { | ||
| 7889 | int ret_val; | ||
| 7890 | const char *file_name; | ||
| 7891 | const char *directory_type; | ||
| 7892 | |||
| 7893 | /* | ||
| 7894 | If a data directory path is passed, check if the path exists and append | ||
| 7895 | table_name to it. | ||
| 7896 | */ | ||
| 7897 |
3/4✓ Branch 0 taken 618792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 618784 times.
|
1237582 | if (data_file_name && |
| 7898 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 618785 times.
|
618792 | (ret_val = append_file_to_dir(thd, data_file_name, table_name))) { |
| 7899 | 6 | file_name = *data_file_name; | |
| 7900 | 6 | directory_type = "DATA DIRECTORY"; | |
| 7901 | 6 | goto err; | |
| 7902 | } | ||
| 7903 | |||
| 7904 | /* | ||
| 7905 | If an index directory path is passed, check if the path exists and append | ||
| 7906 | table_name to it. | ||
| 7907 | */ | ||
| 7908 |
3/4✓ Branch 0 taken 618786 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 618781 times.
|
1237570 | if (index_file_name && |
| 7909 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 618783 times.
|
618786 | (ret_val = append_file_to_dir(thd, index_file_name, table_name))) { |
| 7910 | 3 | file_name = *index_file_name; | |
| 7911 | 3 | directory_type = "INDEX DIRECTORY"; | |
| 7912 | 3 | goto err; | |
| 7913 | } | ||
| 7914 | |||
| 7915 | 618781 | return false; | |
| 7916 | 9 | err: | |
| 7917 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8 times.
|
9 | if (ret_val == ER_PATH_LENGTH) |
| 7918 | 1 | my_error(ER_PATH_LENGTH, MYF(0), directory_type); | |
| 7919 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
|
9 | if (ret_val == ER_WRONG_VALUE) |
| 7920 | 8 | my_error(ER_WRONG_VALUE, MYF(0), "path", file_name); | |
| 7921 | 9 | return true; | |
| 7922 | } | ||
| 7923 | |||
| 7924 | /** If pointer is not a null pointer, append filename to it. */ | ||
| 7925 | |||
| 7926 | 1237577 | int append_file_to_dir(THD *thd, const char **filename_ptr, | |
| 7927 | const char *table_name) { | ||
| 7928 | char tbbuff[FN_REFLEN]; | ||
| 7929 | char buff[FN_REFLEN]; | ||
| 7930 | char *ptr; | ||
| 7931 | char *end; | ||
| 7932 | |||
| 7933 |
2/2✓ Branch 0 taken 1237401 times.
✓ Branch 1 taken 176 times.
|
1237577 | if (!*filename_ptr) return 0; // nothing to do |
| 7934 | |||
| 7935 | /* Convert tablename to filename charset so that "/" gets converted | ||
| 7936 | appropriately */ | ||
| 7937 |
1/2✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
|
176 | size_t tab_len = tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)); |
| 7938 | |||
| 7939 | /* Check that the filename is not too long and it's a hard path */ | ||
| 7940 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 175 times.
|
176 | if (strlen(*filename_ptr) + tab_len >= FN_REFLEN - 1) return ER_PATH_LENGTH; |
| 7941 | |||
| 7942 |
3/4✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 167 times.
|
175 | if (!test_if_hard_path(*filename_ptr)) return ER_WRONG_VALUE; |
| 7943 | |||
| 7944 | /* Fix is using unix filename format on dos */ | ||
| 7945 | 167 | my_stpcpy(buff, *filename_ptr); | |
| 7946 |
1/2✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
|
167 | end = convert_dirname(buff, *filename_ptr, NullS); |
| 7947 | |||
| 7948 |
1/2✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
|
167 | ptr = (char *)thd->alloc((size_t)(end - buff) + tab_len + 1); |
| 7949 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 167 times.
|
167 | if (ptr == nullptr) return ER_OUTOFMEMORY; // End of memory |
| 7950 | 167 | *filename_ptr = ptr; | |
| 7951 |
1/2✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
|
167 | strxmov(ptr, buff, tbbuff, NullS); |
| 7952 | 167 | return 0; | |
| 7953 | } | ||
| 7954 | |||
| 7955 | 9574301 | Comp_creator *comp_eq_creator(bool invert) { | |
| 7956 |
2/2✓ Branch 0 taken 314 times.
✓ Branch 1 taken 9573987 times.
|
9574301 | return invert ? (Comp_creator *)&ne_creator : (Comp_creator *)&eq_creator; |
| 7957 | } | ||
| 7958 | |||
| 7959 | 3068 | Comp_creator *comp_equal_creator(bool invert [[maybe_unused]]) { | |
| 7960 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3068 times.
|
3068 | assert(!invert); // Function never called with true. |
| 7961 | 3068 | return &equal_creator; | |
| 7962 | } | ||
| 7963 | |||
| 7964 | 31921 | Comp_creator *comp_ge_creator(bool invert) { | |
| 7965 |
2/2✓ Branch 0 taken 156 times.
✓ Branch 1 taken 31765 times.
|
31921 | return invert ? (Comp_creator *)<_creator : (Comp_creator *)&ge_creator; |
| 7966 | } | ||
| 7967 | |||
| 7968 | 203341 | Comp_creator *comp_gt_creator(bool invert) { | |
| 7969 |
2/2✓ Branch 0 taken 321 times.
✓ Branch 1 taken 203020 times.
|
203341 | return invert ? (Comp_creator *)&le_creator : (Comp_creator *)>_creator; |
| 7970 | } | ||
| 7971 | |||
| 7972 | 499354 | Comp_creator *comp_le_creator(bool invert) { | |
| 7973 |
2/2✓ Branch 0 taken 104 times.
✓ Branch 1 taken 499250 times.
|
499354 | return invert ? (Comp_creator *)>_creator : (Comp_creator *)&le_creator; |
| 7974 | } | ||
| 7975 | |||
| 7976 | 64251 | Comp_creator *comp_lt_creator(bool invert) { | |
| 7977 |
2/2✓ Branch 0 taken 222 times.
✓ Branch 1 taken 64029 times.
|
64251 | return invert ? (Comp_creator *)&ge_creator : (Comp_creator *)<_creator; |
| 7978 | } | ||
| 7979 | |||
| 7980 | 1990495 | Comp_creator *comp_ne_creator(bool invert) { | |
| 7981 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1990495 times.
|
1990495 | return invert ? (Comp_creator *)&eq_creator : (Comp_creator *)&ne_creator; |
| 7982 | } | ||
| 7983 | |||
| 7984 | /** | ||
| 7985 | Construct ALL/ANY/SOME subquery Item. | ||
| 7986 | |||
| 7987 | @param left_expr pointer to left expression | ||
| 7988 | @param cmp compare function creator | ||
| 7989 | @param all true if we create ALL subquery | ||
| 7990 | @param query_block pointer on parsed subquery structure | ||
| 7991 | |||
| 7992 | @return | ||
| 7993 | constructed Item (or 0 if out of memory) | ||
| 7994 | */ | ||
| 7995 | 2889 | Item *all_any_subquery_creator(Item *left_expr, | |
| 7996 | chooser_compare_func_creator cmp, bool all, | ||
| 7997 | Query_block *query_block) { | ||
| 7998 |
4/4✓ Branch 0 taken 721 times.
✓ Branch 1 taken 2168 times.
✓ Branch 2 taken 416 times.
✓ Branch 3 taken 305 times.
|
2889 | if ((cmp == &comp_eq_creator) && !all) // = ANY <=> IN |
| 7999 |
2/4✓ Branch 0 taken 416 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 416 times.
✗ Branch 3 not taken.
|
416 | return new Item_in_subselect(left_expr, query_block); |
| 8000 |
4/4✓ Branch 0 taken 344 times.
✓ Branch 1 taken 2129 times.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 153 times.
|
2473 | if ((cmp == &comp_ne_creator) && all) // <> ALL <=> NOT IN |
| 8001 | { | ||
| 8002 |
2/4✓ Branch 0 taken 191 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✗ Branch 3 not taken.
|
191 | Item *i = new Item_in_subselect(left_expr, query_block); |
| 8003 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 191 times.
|
191 | if (i == nullptr) return nullptr; |
| 8004 | 191 | Item *neg_i = i->truth_transformer(nullptr, Item::BOOL_NEGATED); | |
| 8005 |
1/2✓ Branch 0 taken 191 times.
✗ Branch 1 not taken.
|
191 | if (neg_i != nullptr) return neg_i; |
| 8006 | ✗ | return new Item_func_not(i); | |
| 8007 | } | ||
| 8008 | Item_allany_subselect *it = | ||
| 8009 |
2/4✓ Branch 0 taken 2282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2282 times.
✗ Branch 3 not taken.
|
2282 | new Item_allany_subselect(left_expr, cmp, query_block, all); |
| 8010 |
4/6✓ Branch 0 taken 1099 times.
✓ Branch 1 taken 1183 times.
✓ Branch 2 taken 1099 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1099 times.
✗ Branch 5 not taken.
|
2282 | if (all) return it->upper_item = new Item_func_not_all(it); /* ALL */ |
| 8011 | |||
| 8012 |
2/4✓ Branch 0 taken 1183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1183 times.
✗ Branch 3 not taken.
|
1183 | return it->upper_item = new Item_func_nop_all(it); /* ANY/SOME */ |
| 8013 | } | ||
| 8014 | |||
| 8015 | /** | ||
| 8016 | Set proper open mode and table type for element representing target table | ||
| 8017 | of CREATE TABLE statement, also adjust statement table list if necessary. | ||
| 8018 | */ | ||
| 8019 | |||
| 8020 | 620843 | void create_table_set_open_action_and_adjust_tables(LEX *lex) { | |
| 8021 | 620843 | TABLE_LIST *create_table = lex->query_tables; | |
| 8022 | |||
| 8023 |
2/2✓ Branch 0 taken 54511 times.
✓ Branch 1 taken 566332 times.
|
620843 | if (lex->create_info->options & HA_LEX_CREATE_TMP_TABLE) |
| 8024 | 54511 | create_table->open_type = OT_TEMPORARY_ONLY; | |
| 8025 | else | ||
| 8026 | 566332 | create_table->open_type = OT_BASE_ONLY; | |
| 8027 | |||
| 8028 |
2/2✓ Branch 0 taken 609913 times.
✓ Branch 1 taken 10930 times.
|
620843 | if (lex->query_block->fields.empty()) { |
| 8029 | /* | ||
| 8030 | Avoid opening and locking target table for ordinary CREATE TABLE | ||
| 8031 | or CREATE TABLE LIKE for write (unlike in CREATE ... SELECT we | ||
| 8032 | won't do any insertions in it anyway). Not doing this causes | ||
| 8033 | problems when running CREATE TABLE IF NOT EXISTS for already | ||
| 8034 | existing log table. | ||
| 8035 | */ | ||
| 8036 | 609913 | create_table->set_lock({TL_READ, THR_DEFAULT}); | |
| 8037 | } | ||
| 8038 | 620843 | } | |
| 8039 | |||
| 8040 | /** | ||
| 8041 | Set the specified definer to the default value, which is the | ||
| 8042 | current user in the thread. | ||
| 8043 | |||
| 8044 | @param[in] thd thread handler | ||
| 8045 | @param[out] definer definer | ||
| 8046 | */ | ||
| 8047 | |||
| 8048 | 33050 | void get_default_definer(THD *thd, LEX_USER *definer) { | |
| 8049 | 33050 | const Security_context *sctx = thd->security_context(); | |
| 8050 | |||
| 8051 | 33050 | definer->user.str = sctx->priv_user().str; | |
| 8052 | 33050 | definer->user.length = strlen(definer->user.str); | |
| 8053 | |||
| 8054 | 33050 | definer->host.str = sctx->priv_host().str; | |
| 8055 | 33050 | definer->host.length = strlen(definer->host.str); | |
| 8056 | |||
| 8057 | 33050 | definer->first_factor_auth_info.plugin = EMPTY_CSTR; | |
| 8058 | 33050 | definer->first_factor_auth_info.auth = NULL_CSTR; | |
| 8059 | 33050 | definer->current_auth = NULL_CSTR; | |
| 8060 | 33050 | definer->first_factor_auth_info.uses_identified_with_clause = false; | |
| 8061 | 33050 | definer->first_factor_auth_info.uses_identified_by_clause = false; | |
| 8062 | 33050 | definer->first_factor_auth_info.uses_authentication_string_clause = false; | |
| 8063 | 33050 | definer->uses_replace_clause = false; | |
| 8064 | 33050 | definer->retain_current_password = false; | |
| 8065 | 33050 | definer->discard_old_password = false; | |
| 8066 | 33050 | definer->alter_status.update_password_expired_column = false; | |
| 8067 | 33050 | definer->alter_status.use_default_password_lifetime = true; | |
| 8068 | 33050 | definer->alter_status.expire_after_days = 0; | |
| 8069 | 33050 | definer->alter_status.update_account_locked_column = false; | |
| 8070 | 33050 | definer->alter_status.account_locked = false; | |
| 8071 | 33050 | definer->alter_status.update_password_require_current = | |
| 8072 | Lex_acl_attrib_udyn::DEFAULT; | ||
| 8073 | 33050 | definer->first_factor_auth_info.has_password_generator = false; | |
| 8074 | 33050 | definer->alter_status.failed_login_attempts = 0; | |
| 8075 | 33050 | definer->alter_status.password_lock_time = 0; | |
| 8076 | 33050 | definer->alter_status.update_failed_login_attempts = false; | |
| 8077 | 33050 | definer->alter_status.update_password_lock_time = false; | |
| 8078 | 33050 | } | |
| 8079 | |||
| 8080 | /** | ||
| 8081 | Create default definer for the specified THD. | ||
| 8082 | |||
| 8083 | @param[in] thd thread handler | ||
| 8084 | |||
| 8085 | @return | ||
| 8086 | - On success, return a valid pointer to the created and initialized | ||
| 8087 | LEX_USER, which contains definer information. | ||
| 8088 | - On error, return 0. | ||
| 8089 | */ | ||
| 8090 | |||
| 8091 | 31738 | LEX_USER *create_default_definer(THD *thd) { | |
| 8092 | LEX_USER *definer; | ||
| 8093 | |||
| 8094 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 31738 times.
|
31738 | if (!(definer = (LEX_USER *)LEX_USER::alloc(thd))) return nullptr; |
| 8095 | |||
| 8096 | 31738 | thd->get_definer(definer); | |
| 8097 | |||
| 8098 | 31738 | return definer; | |
| 8099 | } | ||
| 8100 | |||
| 8101 | /** | ||
| 8102 | Returns information about user or current user. | ||
| 8103 | |||
| 8104 | @param[in] thd thread handler | ||
| 8105 | @param[in] user user | ||
| 8106 | |||
| 8107 | @return | ||
| 8108 | - On success, return a valid pointer to initialized | ||
| 8109 | LEX_USER, which contains user information. | ||
| 8110 | - On error, return 0. | ||
| 8111 | */ | ||
| 8112 | #ifdef WITH_WSREP | ||
| 8113 | 483851 | LEX_USER *get_current_user(THD *thd, LEX_USER *user, bool for_rewrite) { | |
| 8114 | #else | ||
| 8115 | LEX_USER *get_current_user(THD *thd, LEX_USER *user) { | ||
| 8116 | #endif | ||
| 8117 |
3/4✓ Branch 0 taken 483851 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 310 times.
✓ Branch 3 taken 483541 times.
|
483851 | if (!user || !user->user.str) // current_user |
| 8118 | { | ||
| 8119 | 310 | LEX_USER *default_definer = create_default_definer(thd); | |
| 8120 |
1/2✓ Branch 0 taken 312 times.
✗ Branch 1 not taken.
|
312 | if (default_definer) { |
| 8121 | #ifdef WITH_WSREP | ||
| 8122 |
7/10✓ Branch 0 taken 312 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 298 times.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 11 times.
✓ Branch 9 taken 3 times.
|
312 | if (WSREP(thd) && !for_rewrite && |
| 8123 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | (thd->lex->sql_command == SQLCOM_ALTER_USER || |
| 8124 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
|
11 | thd->lex->sql_command == SQLCOM_CREATE_USER || |
| 8125 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
|
10 | thd->lex->sql_command == SQLCOM_DROP_USER || |
| 8126 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
|
9 | thd->lex->sql_command == SQLCOM_RENAME_USER || |
| 8127 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
|
7 | thd->lex->sql_command == SQLCOM_REVOKE || |
| 8128 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
|
6 | thd->lex->sql_command == SQLCOM_REVOKE_ALL || |
| 8129 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
|
5 | thd->lex->sql_command == SQLCOM_GRANT)) { |
| 8130 |
13/28✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 8 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
8 | WSREP_ERROR( |
| 8131 | "Percona XtraDB Cluster doesn't allow use of" | ||
| 8132 | " CURRENT_USER/USER function for USER operation" | ||
| 8133 | " while operating in cluster mode"); | ||
| 8134 | char message[1024]; | ||
| 8135 | 8 | sprintf(message, | |
| 8136 | "Percona XtraDB Cluster doesn't allow use of" | ||
| 8137 | " CURRENT_USER/USER function for USER operation" | ||
| 8138 | " while operating in cluster mode"); | ||
| 8139 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | my_message(ER_UNKNOWN_ERROR, message, MYF(0)); |
| 8140 | 8 | return 0; | |
| 8141 | } | ||
| 8142 | #endif /* WITH_WSREP */ | ||
| 8143 | |||
| 8144 | /* | ||
| 8145 | Inherit parser semantics from the statement in which the user parameter | ||
| 8146 | was used. | ||
| 8147 | This is needed because a LEX_USER is both used as a component in an | ||
| 8148 | AST and as a specifier for a particular user in the ACL subsystem. | ||
| 8149 | */ | ||
| 8150 | default_definer->first_factor_auth_info | ||
| 8151 | 304 | .uses_authentication_string_clause = | |
| 8152 | 304 | user->first_factor_auth_info.uses_authentication_string_clause; | |
| 8153 | 304 | default_definer->first_factor_auth_info.uses_identified_by_clause = | |
| 8154 | 304 | user->first_factor_auth_info.uses_identified_by_clause; | |
| 8155 | 304 | default_definer->first_factor_auth_info.uses_identified_with_clause = | |
| 8156 | 304 | user->first_factor_auth_info.uses_identified_with_clause; | |
| 8157 | 304 | default_definer->uses_replace_clause = user->uses_replace_clause; | |
| 8158 | 304 | default_definer->current_auth.str = user->current_auth.str; | |
| 8159 | 304 | default_definer->current_auth.length = user->current_auth.length; | |
| 8160 | 304 | default_definer->retain_current_password = user->retain_current_password; | |
| 8161 | 304 | default_definer->discard_old_password = user->discard_old_password; | |
| 8162 | 304 | default_definer->first_factor_auth_info.plugin = | |
| 8163 | user->first_factor_auth_info.plugin; | ||
| 8164 | 304 | default_definer->first_factor_auth_info.auth = | |
| 8165 | user->first_factor_auth_info.auth; | ||
| 8166 | 304 | default_definer->alter_status = user->alter_status; | |
| 8167 | 304 | default_definer->first_factor_auth_info.has_password_generator = | |
| 8168 | 304 | user->first_factor_auth_info.has_password_generator; | |
| 8169 | 304 | return default_definer; | |
| 8170 | } | ||
| 8171 | } | ||
| 8172 | |||
| 8173 | 483541 | return user; | |
| 8174 | } | ||
| 8175 | |||
| 8176 | /** | ||
| 8177 | Check that byte length of a string does not exceed some limit. | ||
| 8178 | |||
| 8179 | @param str string to be checked | ||
| 8180 | @param err_msg error message to be displayed if the string is too long | ||
| 8181 | @param max_byte_length max length | ||
| 8182 | |||
| 8183 | @retval | ||
| 8184 | false the passed string is not longer than max_length | ||
| 8185 | @retval | ||
| 8186 | true the passed string is longer than max_length | ||
| 8187 | |||
| 8188 | NOTE | ||
| 8189 | The function is not used in existing code but can be useful later? | ||
| 8190 | */ | ||
| 8191 | |||
| 8192 | 350458 | static bool check_string_byte_length(const LEX_CSTRING &str, | |
| 8193 | const char *err_msg, | ||
| 8194 | size_t max_byte_length) { | ||
| 8195 |
2/2✓ Branch 0 taken 350437 times.
✓ Branch 1 taken 21 times.
|
350458 | if (str.length <= max_byte_length) return false; |
| 8196 | |||
| 8197 | 21 | my_error(ER_WRONG_STRING_LENGTH, MYF(0), str.str, err_msg, max_byte_length); | |
| 8198 | |||
| 8199 | 21 | return true; | |
| 8200 | } | ||
| 8201 | |||
| 8202 | /* | ||
| 8203 | Check that char length of a string does not exceed some limit. | ||
| 8204 | |||
| 8205 | SYNOPSIS | ||
| 8206 | check_string_char_length() | ||
| 8207 | str string to be checked | ||
| 8208 | err_msg error message to be displayed if the string is too long | ||
| 8209 | max_char_length max length in symbols | ||
| 8210 | cs string charset | ||
| 8211 | |||
| 8212 | RETURN | ||
| 8213 | false the passed string is not longer than max_char_length | ||
| 8214 | true the passed string is longer than max_char_length | ||
| 8215 | */ | ||
| 8216 | |||
| 8217 | 14761480 | bool check_string_char_length(const LEX_CSTRING &str, const char *err_msg, | |
| 8218 | size_t max_char_length, const CHARSET_INFO *cs, | ||
| 8219 | bool no_error) { | ||
| 8220 | int well_formed_error; | ||
| 8221 |
1/2✓ Branch 0 taken 14761492 times.
✗ Branch 1 not taken.
|
14761480 | size_t res = cs->cset->well_formed_len(cs, str.str, str.str + str.length, |
| 8222 | max_char_length, &well_formed_error); | ||
| 8223 | |||
| 8224 |
4/4✓ Branch 0 taken 14761491 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 14761381 times.
✓ Branch 3 taken 110 times.
|
14761492 | if (!well_formed_error && str.length == res) return false; |
| 8225 | |||
| 8226 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 62 times.
|
111 | if (!no_error) { |
| 8227 |
1/2✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
|
49 | ErrConvString err(str.str, str.length, cs); |
| 8228 |
1/2✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
|
49 | my_error(ER_WRONG_STRING_LENGTH, MYF(0), err.ptr(), err_msg, |
| 8229 | max_char_length); | ||
| 8230 | } | ||
| 8231 | 111 | return true; | |
| 8232 | } | ||
| 8233 | |||
| 8234 | /* | ||
| 8235 | Check if path does not contain mysql data home directory | ||
| 8236 | SYNOPSIS | ||
| 8237 | test_if_data_home_dir() | ||
| 8238 | dir directory | ||
| 8239 | conv_home_dir converted data home directory | ||
| 8240 | home_dir_len converted data home directory length | ||
| 8241 | |||
| 8242 | RETURN VALUES | ||
| 8243 | 0 ok | ||
| 8244 | 1 error | ||
| 8245 | */ | ||
| 8246 | 19413 | int test_if_data_home_dir(const char *dir) { | |
| 8247 | char path[FN_REFLEN]; | ||
| 8248 | size_t dir_len; | ||
| 8249 |
1/2✓ Branch 0 taken 19413 times.
✗ Branch 1 not taken.
|
19413 | DBUG_TRACE; |
| 8250 | |||
| 8251 |
2/2✓ Branch 0 taken 18590 times.
✓ Branch 1 taken 823 times.
|
19413 | if (!dir) return 0; |
| 8252 | |||
| 8253 |
1/2✓ Branch 0 taken 823 times.
✗ Branch 1 not taken.
|
823 | (void)fn_format(path, dir, "", "", |
| 8254 | (MY_RETURN_REAL_PATH | MY_RESOLVE_SYMLINKS)); | ||
| 8255 | 823 | dir_len = strlen(path); | |
| 8256 |
2/2✓ Branch 0 taken 370 times.
✓ Branch 1 taken 453 times.
|
823 | if (mysql_unpacked_real_data_home_len <= dir_len) { |
| 8257 |
2/2✓ Branch 0 taken 321 times.
✓ Branch 1 taken 49 times.
|
370 | if (dir_len > mysql_unpacked_real_data_home_len && |
| 8258 |
2/2✓ Branch 0 taken 303 times.
✓ Branch 1 taken 18 times.
|
321 | path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR) |
| 8259 | 303 | return 0; | |
| 8260 | |||
| 8261 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
|
67 | if (lower_case_file_system) { |
| 8262 | ✗ | if (!my_strnncoll(default_charset_info, (const uchar *)path, | |
| 8263 | mysql_unpacked_real_data_home_len, | ||
| 8264 | (const uchar *)mysql_unpacked_real_data_home, | ||
| 8265 | mysql_unpacked_real_data_home_len)) | ||
| 8266 | ✗ | return 1; | |
| 8267 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 44 times.
|
67 | } else if (!memcmp(path, mysql_unpacked_real_data_home, |
| 8268 | mysql_unpacked_real_data_home_len)) | ||
| 8269 | 23 | return 1; | |
| 8270 | } | ||
| 8271 | 497 | return 0; | |
| 8272 | 19413 | } | |
| 8273 | |||
| 8274 | /** | ||
| 8275 | Check that host name string is valid. | ||
| 8276 | |||
| 8277 | @param[in] str string to be checked | ||
| 8278 | |||
| 8279 | @return Operation status | ||
| 8280 | @retval false host name is ok | ||
| 8281 | @retval true host name string is longer than max_length or | ||
| 8282 | has invalid symbols | ||
| 8283 | */ | ||
| 8284 | |||
| 8285 | 350459 | bool check_host_name(const LEX_CSTRING &str) { | |
| 8286 | 350459 | const char *name = str.str; | |
| 8287 | 350459 | const char *end = str.str + str.length; | |
| 8288 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 350437 times.
|
350459 | if (check_string_byte_length(str, ER_THD(current_thd, ER_HOSTNAME), |
| 8289 | HOSTNAME_LENGTH)) | ||
| 8290 | 21 | return true; | |
| 8291 | |||
| 8292 |
2/2✓ Branch 0 taken 3153631 times.
✓ Branch 1 taken 350435 times.
|
3504066 | while (name != end) { |
| 8293 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3153629 times.
|
3153631 | if (*name == '@') { |
| 8294 | 2 | my_printf_error(ER_UNKNOWN_ERROR, | |
| 8295 | "Malformed hostname (illegal symbol: '%c')", MYF(0), | ||
| 8296 | 2 | *name); | |
| 8297 | 2 | return true; | |
| 8298 | } | ||
| 8299 | 3153629 | name++; | |
| 8300 | } | ||
| 8301 | 350435 | return false; | |
| 8302 | } | ||
| 8303 | |||
| 8304 | class Parser_oom_handler : public Internal_error_handler { | ||
| 8305 | public: | ||
| 8306 | 17229914 | Parser_oom_handler() : m_has_errors(false), m_is_mem_error(false) {} | |
| 8307 | 3356789 | bool handle_condition(THD *thd, uint sql_errno, const char *, | |
| 8308 | Sql_condition::enum_severity_level *level, | ||
| 8309 | const char *) override { | ||
| 8310 |
2/2✓ Branch 0 taken 1922994 times.
✓ Branch 1 taken 1433795 times.
|
3356789 | if (*level == Sql_condition::SL_ERROR) { |
| 8311 | 1922994 | m_has_errors = true; | |
| 8312 | /* Out of memory error is reported only once. Return as handled */ | ||
| 8313 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1922992 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
1922994 | if (m_is_mem_error && |
| 8314 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | (sql_errno == EE_CAPACITY_EXCEEDED || sql_errno == EE_OUTOFMEMORY)) |
| 8315 | ✗ | return true; | |
| 8316 |
3/4✓ Branch 0 taken 1922993 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1922993 times.
|
1922994 | if (sql_errno == EE_CAPACITY_EXCEEDED || sql_errno == EE_OUTOFMEMORY) { |
| 8317 | 1 | m_is_mem_error = true; | |
| 8318 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (sql_errno == EE_CAPACITY_EXCEEDED) |
| 8319 | 1 | my_error(ER_CAPACITY_EXCEEDED, MYF(0), | |
| 8320 | 1 | static_cast<ulonglong>(thd->variables.parser_max_mem_size), | |
| 8321 | "parser_max_mem_size", | ||
| 8322 | ER_THD(thd, ER_CAPACITY_EXCEEDED_IN_PARSER)); | ||
| 8323 | else | ||
| 8324 | ✗ | my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); | |
| 8325 | 1 | return true; | |
| 8326 | } | ||
| 8327 | } | ||
| 8328 | 3356788 | return false; | |
| 8329 | } | ||
| 8330 | |||
| 8331 | private: | ||
| 8332 | bool m_has_errors; | ||
| 8333 | bool m_is_mem_error; | ||
| 8334 | }; | ||
| 8335 | |||
| 8336 | /** | ||
| 8337 | Transform an SQL statement into an AST that is ready for resolving, using the | ||
| 8338 | supplied parser state and object creation context. | ||
| 8339 | |||
| 8340 | This is a wrapper() for THD::sql_parser() and should generally be used for AST | ||
| 8341 | construction. | ||
| 8342 | |||
| 8343 | The function may optionally generate a query digest, invoke this function as | ||
| 8344 | follows: | ||
| 8345 | |||
| 8346 | |||
| 8347 | @verbatim | ||
| 8348 | THD *thd = ...; | ||
| 8349 | const char *query_text = ...; | ||
| 8350 | uint query_length = ...; | ||
| 8351 | Object_creation_ctx *ctx = ...; | ||
| 8352 | bool rc; | ||
| 8353 | |||
| 8354 | Parser_state parser_state; | ||
| 8355 | if (parser_state.init(thd, query_text, query_length) | ||
| 8356 | { | ||
| 8357 | ... handle error | ||
| 8358 | } | ||
| 8359 | |||
| 8360 | parser_state.m_input.m_has_digest= true; | ||
| 8361 | parser_state.m_input.m_compute_digest= true; | ||
| 8362 | |||
| 8363 | rc= parse_sql(the, &parser_state, ctx); | ||
| 8364 | if (! rc) | ||
| 8365 | { | ||
| 8366 | unsigned char md5[MD5_HASH_SIZE]; | ||
| 8367 | char digest_text[1024]; | ||
| 8368 | bool truncated; | ||
| 8369 | const sql_digest_storage *digest= & thd->m_digest->m_digest_storage; | ||
| 8370 | |||
| 8371 | compute_digest_md5(digest, & md5[0]); | ||
| 8372 | compute_digest_text(digest, & digest_text[0], sizeof(digest_text), & | ||
| 8373 | truncated); | ||
| 8374 | } | ||
| 8375 | @endverbatim | ||
| 8376 | |||
| 8377 | @param thd Thread context. | ||
| 8378 | @param parser_state Parser state. | ||
| 8379 | @param creation_ctx Object creation context. | ||
| 8380 | |||
| 8381 | @return Error status. | ||
| 8382 | @retval false on success. | ||
| 8383 | @retval true on parsing error. | ||
| 8384 | */ | ||
| 8385 | |||
| 8386 | 17229922 | bool parse_sql(THD *thd, Parser_state *parser_state, | |
| 8387 | Object_creation_ctx *creation_ctx) { | ||
| 8388 |
1/2✓ Branch 0 taken 17231547 times.
✗ Branch 1 not taken.
|
17229922 | DBUG_TRACE; |
| 8389 | bool ret_value; | ||
| 8390 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17231547 times.
|
17231547 | assert(thd->m_parser_state == nullptr); |
| 8391 | // TODO fix to allow parsing gcol exprs after main query. | ||
| 8392 | // assert(thd->lex->m_sql_cmd == NULL); | ||
| 8393 | |||
| 8394 | /* Backup creation context. */ | ||
| 8395 | |||
| 8396 | 17231547 | Object_creation_ctx *backup_ctx = nullptr; | |
| 8397 | |||
| 8398 |
3/4✓ Branch 0 taken 741420 times.
✓ Branch 1 taken 16490127 times.
✓ Branch 2 taken 741420 times.
✗ Branch 3 not taken.
|
17231547 | if (creation_ctx) backup_ctx = creation_ctx->set_n_backup(thd); |
| 8399 | |||
| 8400 | /* Set parser state. */ | ||
| 8401 | |||
| 8402 | 17231547 | thd->m_parser_state = parser_state; | |
| 8403 | |||
| 8404 | 17231547 | parser_state->m_digest_psi = nullptr; | |
| 8405 | 17231547 | parser_state->m_lip.m_digest = nullptr; | |
| 8406 | |||
| 8407 | /* | ||
| 8408 | Partial parsers (GRAMMAR_SELECTOR_*) are not supposed to compute digests. | ||
| 8409 | */ | ||
| 8410 |
3/4✓ Branch 0 taken 236332 times.
✓ Branch 1 taken 16993993 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 236332 times.
|
17231547 | assert(!parser_state->m_lip.is_partial_parser() || |
| 8411 | !parser_state->m_input.m_has_digest); | ||
| 8412 | |||
| 8413 | /* | ||
| 8414 | Only consider statements that are supposed to have a digest, | ||
| 8415 | like top level queries. | ||
| 8416 | */ | ||
| 8417 |
2/2✓ Branch 0 taken 11723126 times.
✓ Branch 1 taken 5507199 times.
|
17230325 | if (parser_state->m_input.m_has_digest) { |
| 8418 | /* | ||
| 8419 | For these statements, | ||
| 8420 | see if the digest computation is required. | ||
| 8421 | */ | ||
| 8422 |
2/2✓ Branch 0 taken 11723100 times.
✓ Branch 1 taken 26 times.
|
11723126 | if (thd->m_digest != nullptr) { |
| 8423 | /* Start Digest */ | ||
| 8424 |
1/2✓ Branch 0 taken 11723433 times.
✗ Branch 1 not taken.
|
11723100 | parser_state->m_digest_psi = MYSQL_DIGEST_START(thd->m_statement_psi); |
| 8425 | |||
| 8426 |
2/2✓ Branch 0 taken 76 times.
✓ Branch 1 taken 11723357 times.
|
11723433 | if (parser_state->m_input.m_compute_digest || |
| 8427 |
1/2✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
|
76 | (parser_state->m_digest_psi != nullptr)) { |
| 8428 | /* | ||
| 8429 | If either: | ||
| 8430 | - the caller wants to compute a digest | ||
| 8431 | - the performance schema wants to compute a digest | ||
| 8432 | set the digest listener in the lexer. | ||
| 8433 | */ | ||
| 8434 | 11723433 | parser_state->m_lip.m_digest = thd->m_digest; | |
| 8435 | 11723366 | parser_state->m_lip.m_digest->m_digest_storage.m_charset_number = | |
| 8436 | 11723433 | thd->charset()->number; | |
| 8437 | } | ||
| 8438 | } | ||
| 8439 | } | ||
| 8440 | |||
| 8441 | /* Parse the query. */ | ||
| 8442 | |||
| 8443 | /* | ||
| 8444 | Use a temporary DA while parsing. We don't know until after parsing | ||
| 8445 | whether the current command is a diagnostic statement, in which case | ||
| 8446 | we'll need to have the previous DA around to answer questions about it. | ||
| 8447 | */ | ||
| 8448 | 17230591 | Diagnostics_area *parser_da = thd->get_parser_da(); | |
| 8449 | 17231040 | Diagnostics_area *da = thd->get_stmt_da(); | |
| 8450 | |||
| 8451 | 17231134 | Parser_oom_handler poomh; | |
| 8452 | // Note that we may be called recursively here, on INFORMATION_SCHEMA queries. | ||
| 8453 | |||
| 8454 | 17230407 | thd->mem_root->set_max_capacity(thd->variables.parser_max_mem_size); | |
| 8455 | 17229882 | thd->mem_root->set_error_for_capacity_exceeded(true); | |
| 8456 |
1/2✓ Branch 0 taken 17230034 times.
✗ Branch 1 not taken.
|
17229718 | thd->push_internal_handler(&poomh); |
| 8457 | |||
| 8458 |
1/2✓ Branch 0 taken 17230815 times.
✗ Branch 1 not taken.
|
17230034 | thd->push_diagnostics_area(parser_da, false); |
| 8459 | |||
| 8460 |
1/2✓ Branch 0 taken 17229936 times.
✗ Branch 1 not taken.
|
17230815 | bool mysql_parse_status = thd->sql_parser(); |
| 8461 | |||
| 8462 |
1/2✓ Branch 0 taken 17229383 times.
✗ Branch 1 not taken.
|
17229936 | thd->pop_internal_handler(); |
| 8463 | 17229383 | thd->mem_root->set_max_capacity(0); | |
| 8464 | 17229810 | thd->mem_root->set_error_for_capacity_exceeded(false); | |
| 8465 | /* | ||
| 8466 | Unwind diagnostics area. | ||
| 8467 | |||
| 8468 | If any issues occurred during parsing, they will become | ||
| 8469 | the sole conditions for the current statement. | ||
| 8470 | |||
| 8471 | Otherwise, if we have a diagnostic statement on our hands, | ||
| 8472 | we'll preserve the previous diagnostics area here so we | ||
| 8473 | can answer questions about it. This specifically means | ||
| 8474 | that repeatedly asking about a DA won't clear it. | ||
| 8475 | |||
| 8476 | Otherwise, it's a regular command with no issues during | ||
| 8477 | parsing, so we'll just clear the DA in preparation for | ||
| 8478 | the processing of this command. | ||
| 8479 | */ | ||
| 8480 | |||
| 8481 |
2/2✓ Branch 0 taken 547408 times.
✓ Branch 1 taken 16683189 times.
|
17229976 | if (parser_da->current_statement_cond_count() != 0) { |
| 8482 | /* | ||
| 8483 | Error/warning during parsing: top DA should contain parse error(s)! Any | ||
| 8484 | pre-existing conditions will be replaced. The exception is diagnostics | ||
| 8485 | statements, in which case we wish to keep the errors so they can be sent | ||
| 8486 | to the client. | ||
| 8487 | */ | ||
| 8488 |
2/2✓ Branch 0 taken 547396 times.
✓ Branch 1 taken 12 times.
|
547408 | if (thd->lex->sql_command != SQLCOM_SHOW_WARNS && |
| 8489 |
2/2✓ Branch 0 taken 547394 times.
✓ Branch 1 taken 2 times.
|
547396 | thd->lex->sql_command != SQLCOM_GET_DIAGNOSTICS) |
| 8490 |
1/2✓ Branch 0 taken 547394 times.
✗ Branch 1 not taken.
|
547394 | da->reset_condition_info(thd); |
| 8491 | |||
| 8492 | /* | ||
| 8493 | We need to put any errors in the DA as well as the condition list. | ||
| 8494 | */ | ||
| 8495 |
6/6✓ Branch 0 taken 7906 times.
✓ Branch 1 taken 539502 times.
✓ Branch 2 taken 7866 times.
✓ Branch 3 taken 40 times.
✓ Branch 4 taken 7866 times.
✓ Branch 5 taken 539542 times.
|
547408 | if (parser_da->is_error() && !da->is_error()) { |
| 8496 |
1/2✓ Branch 0 taken 7866 times.
✗ Branch 1 not taken.
|
7866 | da->set_error_status(parser_da->mysql_errno(), parser_da->message_text(), |
| 8497 | parser_da->returned_sqlstate()); | ||
| 8498 | } | ||
| 8499 | |||
| 8500 |
1/2✓ Branch 0 taken 547408 times.
✗ Branch 1 not taken.
|
547408 | da->copy_sql_conditions_from_da(thd, parser_da); |
| 8501 | |||
| 8502 |
1/2✓ Branch 0 taken 547408 times.
✗ Branch 1 not taken.
|
547408 | parser_da->reset_diagnostics_area(); |
| 8503 |
1/2✓ Branch 0 taken 547408 times.
✗ Branch 1 not taken.
|
547408 | parser_da->reset_condition_info(thd); |
| 8504 | |||
| 8505 | /* | ||
| 8506 | Do not clear the condition list when starting execution as it | ||
| 8507 | now contains not the results of the previous executions, but | ||
| 8508 | a non-zero number of errors/warnings thrown during parsing! | ||
| 8509 | */ | ||
| 8510 | 547408 | thd->lex->keep_diagnostics = DA_KEEP_PARSE_ERROR; | |
| 8511 | } | ||
| 8512 | |||
| 8513 |
1/2✓ Branch 0 taken 17229853 times.
✗ Branch 1 not taken.
|
17230597 | thd->pop_diagnostics_area(); |
| 8514 | |||
| 8515 | /* | ||
| 8516 | Check that if THD::sql_parser() failed either thd->is_error() is set, or an | ||
| 8517 | internal error handler is set. | ||
| 8518 | |||
| 8519 | The assert will not catch a situation where parsing fails without an | ||
| 8520 | error reported if an error handler exists. The problem is that the | ||
| 8521 | error handler might have intercepted the error, so thd->is_error() is | ||
| 8522 | not set. However, there is no way to be 100% sure here (the error | ||
| 8523 | handler might be for other errors than parsing one). | ||
| 8524 | */ | ||
| 8525 | |||
| 8526 |
8/12✓ Branch 0 taken 7934 times.
✓ Branch 1 taken 17221919 times.
✓ Branch 2 taken 7934 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7934 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7902 times.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 32 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
|
17229853 | assert(!mysql_parse_status || (mysql_parse_status && thd->is_error()) || |
| 8527 | (mysql_parse_status && thd->get_internal_handler())); | ||
| 8528 | |||
| 8529 | /* Reset parser state. */ | ||
| 8530 | |||
| 8531 | 17229853 | thd->m_parser_state = nullptr; | |
| 8532 | |||
| 8533 | /* Restore creation context. */ | ||
| 8534 | |||
| 8535 |
3/4✓ Branch 0 taken 741420 times.
✓ Branch 1 taken 16488433 times.
✓ Branch 2 taken 740891 times.
✗ Branch 3 not taken.
|
17229853 | if (creation_ctx) creation_ctx->restore_env(thd, backup_ctx); |
| 8536 | |||
| 8537 | /* That's it. */ | ||
| 8538 | |||
| 8539 |
3/4✓ Branch 0 taken 17221253 times.
✓ Branch 1 taken 8071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17221093 times.
|
17229324 | ret_value = mysql_parse_status || thd->is_fatal_error(); |
| 8540 | |||
| 8541 |
4/4✓ Branch 0 taken 17221448 times.
✓ Branch 1 taken 7579 times.
✓ Branch 2 taken 11609205 times.
✓ Branch 3 taken 5612243 times.
|
17229027 | if ((ret_value == 0) && (parser_state->m_digest_psi != nullptr)) { |
| 8542 | /* | ||
| 8543 | On parsing success, record the digest in the performance schema. | ||
| 8544 | */ | ||
| 8545 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11609205 times.
|
11609205 | assert(thd->m_digest != nullptr); |
| 8546 |
1/2✓ Branch 0 taken 11610901 times.
✗ Branch 1 not taken.
|
11609205 | MYSQL_DIGEST_END(parser_state->m_digest_psi, |
| 8547 | &thd->m_digest->m_digest_storage); | ||
| 8548 | } | ||
| 8549 | |||
| 8550 | 17231401 | return ret_value; | |
| 8551 | 17230723 | } | |
| 8552 | |||
| 8553 | /** | ||
| 8554 | @} (end of group Runtime_Environment) | ||
| 8555 | */ | ||
| 8556 | |||
| 8557 | /** | ||
| 8558 | Check and merge "[ CHARACTER SET charset ] [ COLLATE collation ]" clause | ||
| 8559 | |||
| 8560 | @param [in] charset Character set pointer or NULL. | ||
| 8561 | @param [in] collation Collation pointer or NULL. | ||
| 8562 | @param [out] to Resulting character set/collation/NULL on success, | ||
| 8563 | untouched on failure. | ||
| 8564 | |||
| 8565 | Check if collation "collation" is applicable to character set "charset". | ||
| 8566 | |||
| 8567 | If "collation" is NULL (e.g. when COLLATE clause is not specified), | ||
| 8568 | then simply "charset" is returned in "to". | ||
| 8569 | And vice versa, if "charset" is NULL, "collation" is returned in "to". | ||
| 8570 | |||
| 8571 | @returns false on success, | ||
| 8572 | otherwise returns true and pushes an error message on the error stack | ||
| 8573 | */ | ||
| 8574 | |||
| 8575 | 1129354 | bool merge_charset_and_collation(const CHARSET_INFO *charset, | |
| 8576 | const CHARSET_INFO *collation, | ||
| 8577 | const CHARSET_INFO **to) { | ||
| 8578 |
6/6✓ Branch 0 taken 487585 times.
✓ Branch 1 taken 641769 times.
✓ Branch 2 taken 364513 times.
✓ Branch 3 taken 123072 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1129349 times.
|
1493867 | if (charset != nullptr && collation != nullptr && |
| 8579 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 364508 times.
|
364513 | !my_charset_same(charset, collation)) { |
| 8580 | 5 | my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), collation->m_coll_name, | |
| 8581 | 5 | charset->csname); | |
| 8582 | 5 | return true; | |
| 8583 | } | ||
| 8584 | |||
| 8585 |
2/2✓ Branch 0 taken 809069 times.
✓ Branch 1 taken 320280 times.
|
1129349 | *to = collation != nullptr ? collation : charset; |
| 8586 | 1129349 | return false; | |
| 8587 | } | ||
| 8588 | |||
| 8589 | 304024 | bool merge_sp_var_charset_and_collation(const CHARSET_INFO *charset, | |
| 8590 | const CHARSET_INFO *collation, | ||
| 8591 | const CHARSET_INFO **to) { | ||
| 8592 |
4/4✓ Branch 0 taken 196011 times.
✓ Branch 1 taken 108013 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 196008 times.
|
304024 | if (charset == nullptr && collation != nullptr) { |
| 8593 | 3 | my_error( | |
| 8594 | ER_NOT_SUPPORTED_YET, MYF(0), | ||
| 8595 | "COLLATE with no CHARACTER SET in SP parameters, RETURNS, DECLARE"); | ||
| 8596 | 3 | return true; | |
| 8597 | } | ||
| 8598 | 304021 | return merge_charset_and_collation(charset, collation, to); | |
| 8599 | } | ||
| 8600 |